Bash grep一个特定字符串并用sed替换该文件

Bash 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

我需要一些解决方案来替换一些字符串。 我有一个“文件”,内容如下:

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.22272016-09-2110:57:03

我使用此代码在其上获取“免费”值,如下所示:

 grep Free file.txt |grep OK | cut -d K -f 2 |cut -d , -f 2 |cut -d . -f 1
然后我得到了这个结果:

97
88
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
工作原理
  • -E

    这告诉sed使用扩展正则表达式。这减少了我们需要的反斜杠的数量

  • -i.bak

    这说明要在适当的位置更改文件,留下一个备份文件

  • s/(免费。*好的,[^.]*)[.][^,]*/\1%/

    这告诉sed进行您需要的替换。在本例中,sed查找与regex
    (Free.*OK,[^.]*)[.][^,]*
    匹配的文本。这与
    Free
    后跟
    OK,
    后跟除句点以外的任何内容,后跟句点,后跟除逗号以外的任何内容相匹配。括号使从
    Free
    到句点前的最后一个字符的所有内容都保存在组1中

    匹配的文本将替换为
    \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肯定会更简洁、更清晰。