Bash grep一个特定字符串并用sed替换该文件
我需要一些解决方案来替换一些字符串。 我有一个“文件”,内容如下: 23674,ICMP ping,OK,12016-08-2517:11:02Bash grep一个特定字符串并用sed替换该文件,bash,sed,grep,Bash,Sed,Grep,我需要一些解决方案来替换一些字符串。 我有一个“文件”,内容如下: 23674,ICMP ping,OK,12016-08-2517:11:02 23686,平,OK,12016-08-2516:05:04 23689,SSH服务,OK,12016-08-2516:05:49 23693,系统可用空间,OK,97.95602016-08-25 16:06:49 23713,系统可用空间,OK,88.00782016-09-20 18:02:22 23745,C:\Free,OK,63.22272
23686,平,OK,12016-08-2516:05:04
23689,SSH服务,OK,12016-08-2516:05:49
23693,系统可用空间,OK,97.95602016-08-25 16:06:49
23713,系统可用空间,OK,88.00782016-09-20 18:02:22
23745,C:\Free,OK,63.22272016-09-2110:57:03
我使用此代码在其上获取“免费”值,如下所示:
grep Free file.txt |grep OK | cut -d K -f 2 |cut -d , -f 2 |cut -d . -f 1
然后我得到了这个结果:
9788
63
我需要使用以下代码在结果中插入“%”:
grep Free rs.txt |grep OK | cut -d K -f 2 |cut -d , -f 2 |cut -d . -f 1 |sed 's/$/%/g'
结果如下:
grep Free file.txt |grep OK | cut -d K -f 2 |cut -d , -f 2 |cut -d . -f 1
97%88%
63%
我的问题是,如何用新结果“97%”等替换文件上的值,例如“97.9560”。
请给我一个建议。
感谢替换文件中的值:
sed -E -i.bak 's/(Free.*OK,[^.]*)[.][^,]*/\1%/' file.txt
例如:
$ sed -E -i.bak 's/(Free.*OK,[^.]*)[.][^,]*/\1%/' file.txt
$ cat file.txt
23674, ICMP ping, OK, 1, 2016-08-25 17:11:02
23686, Ping, OK, 1, 2016-08-25 16:05:04
23689, SSH Service, OK, 1, 2016-08-25 16:05:49
23693, System Free Space, OK, 97%, 2016-08-25 16:06:49
23713, System Free Space, OK, 88%, 2016-09-20 18:02:22
23745, C:\ Free, OK, 63%, 2016-09-21 10:57:03
工作原理
这告诉sed使用扩展正则表达式。这减少了我们需要的反斜杠的数量-E
这说明要在适当的位置更改文件,留下一个备份文件-i.bak
这告诉sed进行您需要的替换。在本例中,sed查找与regexs/(免费。*好的,[^.]*)[.][^,]*/\1%/
匹配的文本。这与(Free.*OK,[^.]*)[.][^,]*
后跟Free
后跟除句点以外的任何内容,后跟句点,后跟除逗号以外的任何内容相匹配。括号使从OK,
到句点前的最后一个字符的所有内容都保存在组1中 匹配的文本将替换为Free
,这意味着属于组1的文本\1%
,后跟百分号\1
%
- 以下是
awk
版本解决方案:
awk -v OFS=, -F, '/Free.*OK/ {split($4,a,"."); $4=a[1]"%"}1' infile
23674, ICMP ping, OK, 1, 2016-08-25 17:11:02
23686, Ping, OK, 1, 2016-08-25 16:05:04
23689, SSH Service, OK, 1, 2016-08-25 16:05:49
23693, System Free Space, OK, 97%, 2016-08-25 16:06:49
23713, System Free Space, OK, 88%, 2016-09-20 18:02:22
23745, C:\ Free, OK, 63%, 2016-09-21 10:57:03
说明:
此awk
命令将仅对包含Free
后接OK
的行执行操作。由于此文件是一个csv
文件,因此获取第4个字段并将其分成两部分,用
分隔。在附加%
符号后打印感兴趣的部分
sed
最适合查找和替换任务,因为它支持就地替换。但是,可以通过以下方式通过awk实现:
awk -v OFS=, -F, '/Free.*OK/ {split($4,a,"."); $4=a[1]"%"}1' infile > infile.tmp && mv infile.tmp infile
两个
perl
解决方案
$ perl -pe 's/OK,\s*\d+\K\.\d+/%/ if /Free/' ip.txt
23674, ICMP ping, OK, 1, 2016-08-25 17:11:02
23686, Ping, OK, 1, 2016-08-25 16:05:04
23689, SSH Service, OK, 1, 2016-08-25 16:05:49
23693, System Free Space, OK, 97%, 2016-08-25 16:06:49
23713, System Free Space, OK, 88%, 2016-09-20 18:02:22
23745, C:\ Free, OK, 63%, 2016-09-21 10:57:03
正向查找,OK\s*\d+\K
后跟零个或多个空格和一个或多个数字OK,
点后跟一个或多个数字\。\d+
- 替换文本为
,仅当输入行包含%
自由时应用
,
上拆分输入行并更改第四个字段
perl -F, -le '$F[3] =~ s/\.\d+/%/ if /Free/; print join",", @F' ip.txt
若结果与预期一致,则可以使用
perl-i
无备份
或
perl-i.bkp
with backup“这减少了我们需要的反斜杠的数量。”——我在您的RE中没有看到任何需要扩展RE的内容;如果省略,我也看不到任何需要额外反斜杠的内容。另外,我想用\.
@Sundeep替换[.]
——感谢您的澄清。John1024--回答得好。谢谢你的帮助和解释@John1024回答得好@l'l'l我想上下舍入浮点数并不重要?@l'l是的,我舍入浮点数对我来说不重要。干得好;我们同时写了同样的剧本。我稍微喜欢awk-F',/System-Free-Space/{split($4,a,/[.]/);$4=a[1]“%”}{print}
,因为不需要OFS,IMO以1
结尾,表示打印不清楚@东克:艾克是你的朋友。无论何时,只要你发现自己有一条切割和切割管道,那么awk肯定会更简洁、更清晰。