如何使用sed在模式后编辑下一行?

Com*_*PVT 6 sed

使用sed,如何搜索以 结尾的行foo,然后编辑以 开头的下一行#bar

或者换句话说,我想#从下一行中删除注释,如果它#barfoo.

例如:

This is a line ending in foo
#bar is commented out
There are many lines ending in foo
#bar commented out again
Run Code Online (Sandbox Code Playgroud)

我试过:

sed -i 's/^foo\n#bar/foo\nbar/' infile
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 10

sed '/foo$/{n;s/^#bar/bar/;}'
Run Code Online (Sandbox Code Playgroud)

是您要求的直译。n是为了next

现在这在以下情况下不起作用:

line1 foo
#bar line2 foo
#bar
Run Code Online (Sandbox Code Playgroud)

或者:

line1 foo
line2 foo
#bar
Run Code Online (Sandbox Code Playgroud)

由于n不会搜索被拉入模式空间的行foo

在下一行被拉入模式空间后,您可以通过循环回到开头来解决它:

sed '
  :1
  /foo$/ {
     n
     s/^#bar/bar/
     b1
  }'
Run Code Online (Sandbox Code Playgroud)

  • @cuonglm,其他答案中似乎已经涵盖了“P;D”方法。此答案显示了需求方法的 _direct 翻译(搜索 `foo$`,获取下一行,替换)及其限制。 (2认同)

don*_*sti 6

使用N;P;D循环并尝试每次替换:

sed '$!N;s/\(foo\n\)#\(bar\)/\1\2/;P;D' infile
Run Code Online (Sandbox Code Playgroud)

这消除了领先##bar,只有当它遵循结束的行foo,否则它只是打印模式空间不变。


显然,您想取消注释美国镜像,/etc/pacman.d/mirrorlist这是完全不同的事情:

sed -e '/United States/,/^$/{//!s/^#//' -e '}' /etc/pacman.d/mirrorlist
Run Code Online (Sandbox Code Playgroud)

这将取消注释美国部分中的所有镜像 /etc/pacman.d/mirrorlist