我需要在文件中的搜索模式(比如X)之后替换第4行(包含模式Y)。请注意,图案Y也在其他地方使用。所以我无法直接替换它。另请注意,第4行只有一个字Y. 是否有可以轻松完成的脚本命令?可能是" awk"有用但不确定如何使用它。
ex:用于在文件中搜索X的模式。 在文件中我们说
B,
现在我需要替换第4行的Y来说String[] words
。
答案 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,
。 X
和X
之间有多少行,或者在第一个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
是模式名称