使用BSD sed
;
我怎样才能执行以下替换?:
前:
hello hello hello
hello hello hello
后:
hello world hello
hello hello hello
换句话说;我怎样才能只更换这 氮th 发生一个模式?
(或者在这种情况下;这 2ND 发生一个模式?)
答案1
对于任何 POSIX sed
:
$ sed -e'/hello/{' -e:1 -e'$!N;s/hello/world/2;t2' -eb1 -e\} -e:2 -en\;b2 <file
hello world hello
hello hello hello
第一场比赛结束后
/hello/
,我们陷入了循环。在循环内部
:1
,我们将每个N
ext 行读取到模式空间,仅对 nd 出现的情况执行s
ubstitute 命令。2
我们t
估计替换是否成功。如果是,我们会遇到循环:2
,否则重复循环b1
。在循环内部
:2
,我们只打印剩余行直到文件末尾。
请注意,此方法将存储两个之间的所有内容你好在模式空间中。当第一个和第二个文件彼此相距很远时,这将是一个大文件的问题。
答案2
如果使用两个 s 会更容易sed
。事实上,很多事情都是这样,而且常常是这样快点至少在多核系统上也是如此。
: infile =;<<"" \
sed -e's/$/ /;s/hello/&\n\n/g' -e'# marks lines with " $" and splits matches' |
sed -e:n -e's/ $//;t' -eG -e'# sets up a test label, branches for " $"' \
-e's/o\n\{20\}$/o world/' -e'# stacks a byte per match, edits nth match' \
-e'x;N;x;N;s/\n\n*//;tn' -e'# completes the stacking; recycles to top' \
>outfile
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello world hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
(对于 BSD,sed
您需要用文字换行符来代替右侧替换字段中的转义符n
)\n
调整流通常比调整流编辑器更容易。上面的序列就是这样做的:它用尾随空格标记输入中的每一整行,但否则为每次出现的情况分割输出行hello
。然后第二个sed
只需要查找不以空格结尾的行就知道它应该增加其堆栈计数,然后只显式匹配第 20 个。
当然没必要那么严格。你可以放弃领先o
之前\n\{20\}$
并将其保留在替换件上。那只会取代从从第 20 个匹配到输入中的最后一个。或者您可以只\n\{20,25\}
处理一系列匹配。甚至:\n\{20,25\}\(\n\{15\}\)*$
处理 20,25 的范围以及此后每 10,15 次出现的情况。
这是一个输出示例,给出了与最后提到的相同的输入......
hello hello hello hello hello hello hello hello hello
hello hello hello hello hello hello hello hello hello
hello hello world hello world hello world hello world hello world hello world hello hello
hello hello hello hello hello hello hello hello world hello world
hello world hello world hello world hello world hello hello hello hello hello
hello hello hello hello hello world hello world hello world hello world hello world
hello world hello hello hello hello hello hello hello hello