我以为我理解了sed,但我猜不是。我有以下两个文件,其中我想用一个不同的行替换“why”和“huh”行。根本没有空格。
的test.txt:
hi
why
huh
hi
why
huh
的test2.txt:
1
hi
why
huh
hi
why
huh
以下两个命令给出以下结果:
sed "N; s/<why\/>\n<huh\/>/yo/g" test.txt > out.txt
out.txt:
hi
why
huh
hi
yo
sed "N; s/<why\/>\n<huh\/>/yo/g" test2.txt > out2.txt
out2.txt:
1
hi
yo
hi
why
huh
我对sed不了解什么?为什么两个输出文件都不包含以下内容:
hi
yo
hi
yo
答案 0 :(得分:8)
你的表达几乎是正确的,但它有两个问题:
如果您想将why
作为单词匹配,则应将\<
和\>
放在其周围。你确实在它周围放了<
和\/>
。所以,第一次修正是:
$ sed 'N; s/\<why\>\n\<huh\>/yo/g' test.txt
但它也不起作用:
$ sed 'N; s/\<why\>\n\<huh\>/yo/g' test.txt
hi
why
huh
hi
yo
为什么它只替换第二对线?好吧,在第一行中,N
命令会将why
连接到hi
,并在pattern space中保留字符串hi\nwhy
。此字符串与s///
命令不匹配,因此只打印该行。下一次,您在模式空间中拥有字符串huh
并将hi
连接到它。在下一行中,您将在要替换的模式空间中使用why\nhuh
。
解决方案是仅在当前行为why
时使用address /^why$/
连接下一行:
$ sed '/^why$/ {N; s/\<why\>\n\<huh\>/yo/g}' test.txt
hi
yo
hi
yo
答案 1 :(得分:3)
在brandizzi的答案中,美妙地解释了它没有取代两对线的原因。
然而,如果我们更进一步。假设我们有以下文件,我们想用“pure \ nmilk”替换“apple \ njuice”。
的test.txt
water water water water
water water water apple
juice water water apple
juice water water water
模式过滤方式不起作用。
sed '/apple/ {N; s/apple\njuice/pure\nmilk/g}' test.txt
water water water water
water water water pure
milk water water apple
juice water water water
因为来自test.txt的第二个苹果已经被N连接到前一行,所以没有被模式过滤器捕获。
我能想到的一个解决方案是使用分支连接所有行然后进行替换。
sed ':a;N;$!ba;s/apple\njuice/pure\nmilk/g' test.txt
water water water water
water water water pure
milk water water pure
milk water water water
看起来很愚蠢,但我还没有想到更好的方法。
答案 2 :(得分:1)
这适用于test.txt
文件:
sed '/hi/! { N ; s/why\nhuh/yo/ }' test.txt
这意味着:
如果未在一行中找到hi
(它将是why
),请阅读下一个并用yo
替换所有内容。否则直接打印(hi
时)。
输出:
hi
yo
hi
yo