你好,假设我有一个文件,例如:
$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
更新:替换所有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
,则将其删除。否则,打印/删除第一行并重复。