如何用sed找到并替换前n个外观?

时间:2014-08-16 02:54:08

标签: bash sed

我一直在使用这段代码来替换文件中第一次出现的模式:

sed "0,\#pattern#s##replacement#" input.txt > output.txt

要替换文件中前五次出现的模式,我使用了这个:

sed "0,\#pattern#s##replacement#" input.txt > output1.txt
sed "0,\#pattern#s##replacement#" output1.txt > output2.txt
sed "0,\#pattern#s##replacement#" output2.txt > output3.txt
sed "0,\#pattern#s##replacement#" output3.txt > output4.txt
sed "0,\#pattern#s##replacement#" output4.txt > output5.txt
mv output5.txt output.txt

如何更简单地将匹配的第一个n外观替换为sed

3 个答案:

答案 0 :(得分:4)

对于sed(我个人使用awk)来说,这不是一项自然的工作,但以下情况应该有效:

 sed '1{x;s/.*/00000/;x};/PATTERN/{x;s/0//;x;t1;b;:1;s/PATTERN/REPLACEMENT/}'

第一个0命令中s s字符串的长度是替换次数;我使用0来生成sed命令,如下所示:

 sed "1{x;s/.*/$(printf %*d $COUNT 0)/;x};
     /$PATTERN/{x;s/0//;x;t1;b;:1;s/$PATTERN/$REPLACEMENT/}"

使用Gnu sed,您可以将t1;b;:1;替换为T;

这是awk版本:

 awk 'N&&sub(PAT,REPL){N--};1' N=5 PAT="pattern" REPL="replacement"

答案 1 :(得分:2)

sed没有自然计数能力。你可以做这样奇怪的事。

sed -r '
  /pattern/ {
    s//replacement/
    x
    s/.*/&x/ 
    t clear
    : clear
    s/x{3}/&/
    x
    T
    q
  }
' file

在最后一个替换命令中,将x&s的数量设置为您想要的替换数量。实际上,此命令需要与-i一起使用才能修改文件,因为它在执行请求的替换次数后退出并停止处理文件。

以上评论:

sed -r '
  /pattern/ {
    s//replacement/
    x          # exchange spaces
    s/.*/&x/   # increment number of x s
    t clear    # reset the successul substitition flag
    : clear    
    s/x{3}/&/  # test for the required number of x s to quit
    x          # exchange spaces
    T          # if substitution was not successful, next cycle
    q          # quit
  }
' file

这是另一个想法,但它最多可以替换10个。

sed -r '
  1{x;s/^/0/;x}
  /pattern/ {
    s//replacement/
    x
    y/0123456789/1234567890/
    tx :x   # reset substitution flag
    s/3/&/
    x; T; q
}'

如果您使用的sed没有T命令,则可以使用t命令将其替换为T q 命令。变化:

t quit
b
: quit
q

{{1}}

答案 2 :(得分:1)

你也可以考虑perl:

perl -lpe 's#pattern#s##replacement# and $n++ if $n < 5' input