【问题标题】:Replace a specific pattern with SED用 SED 替换特定模式
【发布时间】:2013-07-08 18:18:49
【问题描述】:

我需要有关如何编写 SED 单行(无 awk)的帮助,该行用相同长度的模式替换一行的子字符串。 例如,如果文件如下所示:

守护进程 www X=1 ***Y=1,2,2*** Z= 守护进程 www X=1 ***Y=1,2,2,1,3,4,5*** Z=4 守护程序邮件 a=3

我只想更改包含 "daemon www" 和子字符串 Y=.. 的行,其中包含相同数量的零。 (#,#,#,#的数量未知)。

输出文件应如下所示:

守护进程 www X=1 ***Y=0,0,0*** Z=4 守护进程 www X=1 ***Y=0,0,0,0,0,0,0*** Z=4 守护程序邮件 a=3

有什么想法吗?谢谢!

【问题讨论】:

  • awk 也承认单行,你知道...
  • 为什么只有sed?这是作业吗?那些***真的存在吗?
  • @Jaypal:除了 sed 之外,为什么会有人需要任何东西? SED!
  • 对不起。星号应该突出显示“Y=...”。
  • 不是作业。工作项目。我敢肯定它只能用 sed...

标签: regex linux sed


【解决方案1】:

一种方式:

 sed '/daemon www.*Y=/{:l s/\(Y=\(0,\)*\)[0-9]*/\10/;/Y=\(0,\)*0\([^,0-9]\|$\)/!bl}' input

一些解释:

if this line contains daemon www and Y=        #  /daemon www.*Y=/{
    loop                                       # :l
      a. find Y= and zeros followed by commas  # s/\(Y=\(0,\)*\)
      b. find a series of digits               # [0-9]*
      c. replace matches in 'a' and 'b' with   # /\10/g
         'a' and 0 
      d. jump to loop if cannot match the 
         desired pattern: Y=0,0..,0            # /Y=\(0,\)*0
      e. and the pattern in d ends with a 
         non-digit non-comma character or the 
         end of line                           # \([^,0-9]\|$\)/!bl

【讨论】:

  • 你的输出看起来很奇怪......使用GNU sed version 4.2.1
  • 仍然很无聊。 * 似乎也变成了 0。 daemon www X=1 ***Y=0,0,0,0,0,0,0000 Z=4
  • 就是这样!太好了!!
  • 我能得到一个简短的解释吗? SED 文档很糟糕。
  • 一开始看起来很复杂,但现在很有意义:) 谢谢!!
【解决方案2】:

我会使用awk。但是如果你真的必须使用sed,你可以忽略它。

awk '/daemon www.*Y=*/{for(i=1;i<=NF;i++) ($i~/Y=/)?gsub(/[0-9]/,"0",$i):$i}1' file

测试:

$ cat file
daemon www X=1 ***Y=1,2,2*** Z=
daemon www X=1 ***Y=1,2,2,1,3,4,5*** Z=4
daemon mail a=3 Y=3,45,
$ awk '/daemon www.*Y=*/{for(i=1;i<=NF;i++) ($i~/Y=/)?gsub(/[0-9]/,"0",$i):$i}1' file
daemon www X=1 ***Y=0,0,0*** Z=
daemon www X=1 ***Y=0,0,0,0,0,0,0*** Z=4
daemon mail a=3 Y=3,45,

【讨论】:

  • awk 'BEGIN{print "Thank You, Fred!"}' :)
【解决方案3】:

试试:

sed '/^daemon www.*Y/{s/[0-9]\([,*]\)/0\1/g}'

在行动:

$ cat input
daemon www X=1 ***Y=1,2,2*** Z=
daemon www X=1 ***Y=1,2,2,1,3,4,5*** Z=4
daemon mail a=3

$ sed '/^daemon www.*Y/{s/[0-9]\([,*]\)/0\1/g}' input
daemon www X=1 ***Y=0,0,0*** Z=
daemon www X=1 ***Y=0,0,0,0,0,0,0*** Z=4
daemon mail a=3

【讨论】:

  • outch,很高兴有人关注
  • +1 虽然你真的不需要在字符类中转义。
  • 啊,从头开始。您已将其从 sed in action 中删除。
【解决方案4】:

试试这个:

sed -e 's/^\(daemon www X=1 .*Y=\)[0-9]\+/\10/' -e 's/,[0-9]\+/,0/g'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-26
    • 2018-01-16
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 2013-11-11
    相关资源
    最近更新 更多