我正在使用sed
来查找和替换文件中模式的第一个外观:
sed -i "0,\#pattern#s##replacement#" ./file.txt
如何告诉它跳过包含{
的任何行。以下是输入示例:
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the pattern, and not the character, so it will be changed.
以下是示例输出:
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the replacement, and not the character, so it will be changed.
{
,则不会对该文件进行任何更改。如何使用sed
查找和替换项目的第一个外观,但跳过包含其他模式的任何行,在本例中为{
?
答案 0 :(得分:2)
您只需添加一个小修改:
sed -i -e '/{/!s/pattern/replacement/' file
如果行匹配s
,它会跳过更改任何内容(跳过/{/
)。 !
否定它并允许s
。
这是同义词:
sed -i -e '/{/b; s/pattern/replacement/' file
b
使其跳过(跳到结束)。
测试:
# sed '/{/!s/pattern/replacement/' file
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the replacement, and not the character, so it will be changed.
如果您需要替换多个模式,请添加g
:
sed -i -e '/{/!s/pattern/replacement/g' file
使用awk
:
awk '!/{/ && !x { x = sub(/pattern/, "replacement") } { a[NR] = $0 }
END { for (i = 1; i <= NR; ++i) print a[i] }' file
输入:
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the pattern, and not the character, so it will be changed.
This line has the pattern, and not the character, so it will be changed.
输出:
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the replacement, and not the character, so it will be changed.
This line has the pattern, and not the character, so it will be changed.
直接对文件进行更改:
awk '!/{/ && !x { x = sub(/pattern/, "replacement") } { a[NR] = $0 }
END { for (i = 1; i <= NR; ++i) print a[i] > FILENAME }' file
使用gsub
代替sub
替换第一条匹配线上的多个匹配。
答案 1 :(得分:2)
这可能适合你(GNU sed):
sed '/{/b;/pattern/{s//replacement/;:a;n;ba}' file
在匹配第一个模式时跳过包含{
的任何行,将其替换为替换,然后将剩余的行打印到文件结尾。
答案 2 :(得分:1)
您可以尝试awk
awk '!/{/ {sub(/pattern/,"replacement")}1' file
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the replacement, and not the character, so it will be changed.
这会将pattern
替换为replacement
,而不是{
更改文件(模拟sed -i
)
awk '!/{/ {sub(/pattern/,"replacement")}1' file > tmp && mv tmp file
答案 3 :(得分:1)
使用perl会更简单:
perl -pe 's/pattern/replacement/ unless(/\{/)' your_file
到位替换:
perl -pi -e 's/pattern/replacement/ unless(/\{/)' your_file
答案 4 :(得分:1)
仅针对此文件的一个替换修改Jotne解决方案:
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the pattern, and not the character, but another pattern.
This line has the pattern, and not the character, but is the second line.
是
awk 'BEGIN {b = 0} !/{/ && !b { b=sub(/pattern/,"replacement");}1' file
并给出
This line does not have the item, so it is skipped.
This line has the pattern, but also has {, so it is skipped too.
This line has the replacement, and not the character, but another pattern.
This line has the pattern, and not the character, but is the second line.
Gnu awk也有一个就位选项:
gawk -i inplace 'BEGIN {b = 0} !/{/ && !b { b=sub(/pattern/,"replacement");}1' file