我将使用 sed 替换相应行中第三次(或更一般的第 n 次)出现的指定匹配正则表达式。到目前为止我只能做第一个:
$cat file
# Golden dictionary is a versatile multi purpose reference
# Copyright (C) 2004-2008 A
# Copyright (C) 2008-2015 B
# Copyright (C) 2015-2016 C
到目前为止我只能
$ cat file| sed -E '0,/copy/I s//No-&/'
# Golden dictionary is a versatile multi purpose reference
# No-Copyright (C) 2004-2008 A
# Copyright (C) 2008-2015 B
# Copyright (C) 2015-2016 C
只在第3场比赛时如何做到这一点?
答案1
使用 ed,在第三个不区分大小写的“copy”前面加上“No-”前缀将是:
ed -s file <<< $'/[Cc][Oo][Pp][Yy]/\n//\n//\ns//No-&/\nw\nq' > /dev/null
命令是:
/[Cc][Oo][Pp][Yy]/
-- 以手动不区分大小写的方式搜索“copy://
-- 重复搜索两次s//No-&/
-- 用“No-”前缀替换最后一个匹配项w
-- 将更改文件写入磁盘q
——退出编辑
使用 sed,您可以做一些前期工作来查找要更改的行号:
sed -i $(grep -in copy file |awk -F: 'NR==3 { print $1 }')'s/copy/No-&/i' input
从左到右工作,
-i
-- GNU sed 的就地编辑选项$( ... )
-- 查找“copy”的第三个匹配的行号grep -in copy file
-- 查找单词“copy”,不区分大小写file
并报告匹配的行号awk -F: 'NR==3 { print $1 }'
-- 在 grep 输出的第 3 行,用冒号分割该行并报告第 1 列(行号)
s/copy/No-&/i
-- 将“copy”替换为“No-copy”,不区分大小写
答案2
使用awk
,计算包含字符串 的行数Copyright
,当我们到达第三个这样的行时,对该行上第一个这样的出现执行替换:
awk '/Copyright/ && ++n == 3 { sub("Copyright", "No-&") } { print }' file
&
在替换中使用意味着使用正则表达式匹配的任何内容。在这种情况下,它将是Copyright
要插入的字符串。这(使用&
)也适用于例如sed
。
第一个块之前的条件,
/Copyright/ && ++n == 3
会将字符串Copyright
与当前行进行匹配。如果匹配,n
则会递增。如果 的增量值n
等于 3,则执行该块。
测试:
$ cat file
# Golden dictionary is a versatile multi purpose reference
# Copyright (C) 2004-2008 A
# Copyright (C) 2008-2015 B
# Copyright (C) 2015-2016 C
# Golden dictionary is a versatile multi purpose reference
# Copyright (C) 2004-2008 A
# Copyright (C) 2008-2015 B
# Copyright (C) 2015-2016 C
(该文件与您的相同,但内容重复一次)
$ awk '/Copyright/ && ++n == 3 { sub("Copyright", "No-&") } { print }' file
# Golden dictionary is a versatile multi purpose reference
# Copyright (C) 2004-2008 A
# Copyright (C) 2008-2015 B
# No-Copyright (C) 2015-2016 C
# Golden dictionary is a versatile multi purpose reference
# Copyright (C) 2004-2008 A
# Copyright (C) 2008-2015 B
# Copyright (C) 2015-2016 C