替换文件中搜索模式下方的第n行

时间:2015-09-03 12:44:53

标签: regex awk sed grep

我需要在文件中的搜索模式(比如X)之后替换第4行(包含模式Y)。请注意,图案Y也在其他地方使用。所以我无法直接替换它。另请注意,第4行只有一个字Y. 是否有可以轻松完成的脚本命令?可能是" awk"有用但不确定如何使用它。

ex:用于在文件中搜索X的模式。 在文件中我们说

B,

现在我需要替换第4行的Y来说String[] words

4 个答案:

答案 0 :(得分:3)

你可以在awk中使用这样的东西:

awk '/X/ || f == 1 && sub(/Y,/, "B,") { ++f } 1' file

当模式f匹配时,这会将标记/X/设置为1(或 true )。如果f为真且sub返回 true 值(执行替换时会执行此操作),则s将设置为true并{{1返回false。这意味着f仅为真一次,因此只会替换一次f

使用与您在问题中显示的示例略有不同的示例进行测试:

Y,

如您所见,仅替换了第一个$ cat file Y, A, X, C, D, Y, A, X, Y, $ awk '/X/ && !s { f = 1 } f && sub(/Y,/, "B,") { s = 1; f = 0 } 1' file Y, A, X, C, D, B, A, X, Y, 后的Y,XX之间有多少行,或者在第一个Y,之前有多个X并不重要。

如果要在Y,出现后替换所有出现的Y,,那么您可以简化代码:

X

与以前一样,这会在找到awk '/X/ { f = 1 } f { sub(/Y,/, "B,") } 1' file 时设置标记f。然后,每当从该点开始发现/X/时,它就会执行替换。

使用与上面相同的输入进行测试:

Y,

答案 1 :(得分:2)

对于少量的行:

sed '/X/ { n; n; n; s/Y/B/; }' filename

这非常简单:

/X/ {      # If the current line matches /X/
  n        # fetch the next line (printing the current one unchanged)
  n        # and the next line
  n        # and the next line
  s/Y/B/   # and in that line, replace Y with B.
}

由于这对于大数字来说有点笨拙,你可能会考虑在这种情况下使用awk:

awk 'NR == marker { sub(/Y/, "B") } /X/ { marker = NR + 3 } 1' filename

那是:

NR == marker { sub(/Y/, "B") }  # if the current line is marked, substitute
/X/ { marker = NR + 3 }         # if the current line matches /X/, mark the one
                                # that comes three lines later for substitution
1                               # print

答案 2 :(得分:2)

另一个awk替代方案,类似于Tom Fenech,但也许更容易阅读

 awk 'x&&!s{s=sub(/Y/,"B")} /X/{x=1} 1'

如果在x中而未被替换,则替换;当匹配X时,将上下文设置为x;打印。以上将取代第一个实例。如果您只想在第n行替换,可以执行以下更改。

awk 'x&&c++==2{sub(/Y/,"B")} /X/{x=1} 1'

这将在第一次X匹配后替换第三行(计数器从零开始)。或者,如果你想看到" 3"在脚本中,

awk 'x&&++c==3{sub(/Y/,"B")} /X/{x=1} 1'

答案 3 :(得分:0)

我找到了另一种在vim中使用映射键的方法

:map z n4j^cwY<esc>

说明:

    接下来是
  • n
  • 4j下面有4行
  • cw是更改字词
  • Y是模式名称