使用sed换行元素



你好,假设我有一个文件,例如:

$OUT some text
some text 
some text
$OUT
$OUT
$OUT

如何使用sed将3个$OUT替换为"replace-thing"

并获得

$OUT some text
some text 
some text
replace-thing

使用sed:

sed -n '1h; 1!H; ${g; s/$OUTn$OUTn$OUT/replace-thing/g; p;}' file

GNU sed不需要p后面的分号。

带注释

sed -n '    # without printing every line:
# next 2 lines read the entire file into memory
1h      # line 1, store current line in the hold space
1!H     # not line 1, append a newline and current line to hold space
# now do the search-and-replace on the file contents
${      # on the last line:
g   # replace pattern space with contents of hold space
s/$OUTn$OUTn$OUT/replace-thing/g   # do replacement
p   # and print the revised contents
}
' file

这就是我只在非常简单的事情上使用sed的主要原因:一旦你开始使用较少使用的命令,你就需要大量的注释来理解程序。

请注意,注释版本在基于MacOS的BSD上不起作用——注释会破坏它,但删除它们是可以的。


在普通bash:中

pattern=$'$OUTn$OUTn$OUT'      # using ANSI-C quotes
contents=$(< file)
echo "${contents//$pattern/replace-thing}"

perl的一行代码:

perl -0777 -pe 's/$OUT(n$OUT){2}/replace-thing/g' file
对于这个特定的任务,我建议使用awk。(希望这也是一种选择(

更新:替换所有3个$OUT使用:(感谢@thanassp和@glenn jackman(

cat input.txt | awk '
BEGIN {
i = 0
p = "$OUT" # Pattern to match
n = 3 # N matches
r = "replace-thing"
}
$0 == p {
++i
if(i == n){
print(r)
i = 0 #reset counter (optional)
}
}
$0 != p {
i = 0
print($0)
}'

如果您只想更换第三次使用$OUT,请使用:

cat input.txt | awk '
BEGIN {
i = 0
p = "\$OUT" # Pattern to match
n = 3 # Nth match
r = "replace-thing"
}
$0 ~ p {
++i
if(i == n){
print(r)
}
}
i <= n || $0 !~ p {
print($0)
}'

这可能对你有用(GNU sed(:

sed -E ':a;N;s/[^n]*/&/3;Ta;/^($OUTn?){3}$/d;P;D' file

在图案空间中收集3行,如果这3行中的每一行都包含$OUT,则将其删除。否则,打印/删除第一行并重复。

最新更新