我使用sed -i 's/AAA/ZZZ/g' filename
将文件中每次出现的"AAA"替换为"ZZZ"。我需要将"AAA"的每个偶数外观替换为"ZZZ",例如:
This is a AAA sentence. AAA
This is another AAA sentence.
This is yet AAA another AAA sentence.
This is AAA stillAAA AAA yet AAA another AAA sentence.
这将变成:
This is a AAA sentence. ZZZ
This is another AAA sentence.
This is yet ZZZ another AAA sentence.
This is ZZZ stillAAA ZZZ yet AAA another ZZZ sentence.
如何替换匹配的每个偶数外观?
下面是一个简短的gnu awk
版本
awk '{ORS=NR%2==0?"ZZZ":RS}1' RS="AAA" file
This is a AAA sentence. ZZZ
This is another AAA sentence.
This is yet ZZZ another AAA sentence.
This is ZZZ stillAAA ZZZ yet AAA another ZZZ sentence.
awk
是比sed
更好的工具。考虑一下这个awk命令:
awk -F 'AAA' '{for (i=1; i<NF; i++) {OFS=c%2?"ZZZ":FS; printf "%s%s", $i, OFS; c++}
print $NF}' file
This is a AAA sentence. ZZZ
This is another AAA sentence.
This is yet ZZZ another AAA sentence.
This is ZZZ stillAAA ZZZ yet AAA another ZZZ sentence.
该awk将输入字段分隔符设置为AAA
,并根据计数器是奇数还是偶数在AAA
和ZZZ
之间切换输出字段分隔符。每次计数器为偶数时,OFS被设置为AAA
,而当计数器为奇数时,则OFS被设为ZZZ
这里有一个perl解决方案:
$ cat inp
This is a AAA sentence. AAA
This is another AAA sentence.
This is yet AAA another AAA sentence.
This is AAA stillAAA AAA yet AAA another AAA sentence.
$ perl -pe 'my $line = "" ; while(<>){ $line=$line.$_} $line =~ s/(.*?AAA.*?)AAA/1ZZZ/mgs; print $line;' < inp
This is another AAA sentence.
This is yet ZZZ another AAA sentence.
This is ZZZ stillAAA ZZZ yet AAA another ZZZ sentence.
在这里,首先我将整个文件累积在一个变量$line
中&然后,我用ZZZ替换AAA的每个交替出现;使用非贪婪匹配。
Perl:
perl -wpe 'BEGIN{$/="AAA"} $.%2 or s/AAA/ZZZ/' foo.txt
您也可以使用sed
:
sed -n -e '1,$ {
:oddline s/AAA/n/g; :odd s/n/AAA/m; t even ;p;N;s/.*n//;b oddline ;
:evenline s/AAA/n/g; :even s/n/ZZZ/m; t odd ; p;N;s/.*n//;b evenline ;
}' << _END_
This is a AAA sentence. AAA
This is another AAA sentence.
This is yet AAA another AAA sentence.
This is AAA stillAAA AAA yet AAA another AAA sentence.
_END_
sed脚本遍历所有行并记住奇数/偶数替换(跨行)。在模式空间中,所有AAA首先用换行符替换,然后一次用AAA或ZZZ替换一个。为了切换到下一行,它首先被附加(N
),然后删除前一行(s/.*n//
)。
sed "1 h;1 !H;$ {x;l;s/=/=e/g;s/²/=c/g;s/AAA/²/g;s/²([^²]{1,})²/²1ZZZ/g;s/²/AAA/g;s/=c/²/g;s/=e/=/g;}" YourFile
使用替换(由于AAA可能在a.*内部)确保即使有替换字符在内部,也可以在之前和之后进行双重翻译
这可能对你有用(GNU sed):
sed -r ':a;$!{N;ba};/x00/q1;s/AAA/x00/g;s/(x00)([^x00]*)1/AAA2ZZZ/g' file
这会将文件拖入内存,然后用一个唯一字符替换所有出现的AAA
。然后,该唯一字符的每一次奇数和偶数出现分别被CCD_ 15和CCD_ 16代替。
注意:如果unique character
不是唯一的,则不对文件进行任何更改,并设置1
的错误代码。
第二种方法比较冗长,但可用于更改第N个值,并且不依赖于unique value
:
sed -r 's/AAA/n&/g;/n/!b;G;:a;s/$/#/;s/#{2}$//;/n$/s/nAAA/nZZZ/;s/n//;/n.*n/ba;P;s/^.*n//;h;d' file
它将所需模式的出现次数存储在保留空间中,并在遇到具有这种模式的行时检索它。