Regex 仅当使用sed的字符串不存在时,才将该字符串添加到行尾
我试图将一个名为“SPEC1”的字符串添加到以BEGIN开头的行的末尾,但前提是该字符串不存在。某些匹配的行可能已经有字符串,也可能尚未有字符串 我的示例文件如下所示:Regex 仅当使用sed的字符串不存在时,才将该字符串添加到行尾,regex,string,bash,awk,sed,Regex,String,Bash,Awk,Sed,我试图将一个名为“SPEC1”的字符串添加到以BEGIN开头的行的末尾,但前提是该字符串不存在。某些匹配的行可能已经有字符串,也可能尚未有字符串 我的示例文件如下所示: BEGIN value1 value2 value3 SPEC1 some_other_line1 BEGIN value1 value2 value3 value4 some_other_line2 BEGIN value1 value2 BEGIN value1 value2 value3 SPEC1 some_other
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4
some_other_line2
BEGIN value1 value2
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
sed '/BEGIN/ {
s/ \+SPEC1//g
s|\(.*\)|\1 SPEC1|
}' file
结果应该是这样的:
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4
some_other_line2
BEGIN value1 value2
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
sed '/BEGIN/ {
s/ \+SPEC1//g
s|\(.*\)|\1 SPEC1|
}' file
我正在使用sed来尝试实现这一点。我当前的sed解决方案如下:
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4
some_other_line2
BEGIN value1 value2
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
sed '/BEGIN/ {
s/ \+SPEC1//g
s|\(.*\)|\1 SPEC1|
}' file
对上述情况的解释:
awk '/^BEGIN/&& !/SPEC1$/{$0=$0 FS "SPEC1"}1' inputfile
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
如果希望将SPEC1
作为变量:
awk -v string="SPEC1"$"" '/^BEGIN/&& $0 !~ string{$0=$0 FS string}1' input
Awk
解决方案:
awk '$1=="BEGIN" && $NF!="SPEC1"{ $(NF+1)="SPEC1" }1' file
$ sed -r '/^BEGIN/s/( SPEC1)?$/ SPEC1/' data
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
-当前记录的第一个字段$1
-当前输入记录中的字段数(指向最后一个字段)$NF
-为最后一个字段之后的下一个字段生成值$(NF+1)
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
改进OP中提到的
sed
版本
$ sed '/BEGIN/{/ SPEC1/! s/$/ SPEC1/}' ip.txt
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
如果行包含/BEGIN/
(如果需要,添加行起始限定符)BEGIN
/SPEC1/代码>如果行不包含
(如果需要,添加行尾限定符)SPEC1
将s/$/SPEC1/
添加到行尾SPEC1
sed
解决方案:
awk '$1=="BEGIN" && $NF!="SPEC1"{ $(NF+1)="SPEC1" }1' file
$ sed -r '/^BEGIN/s/( SPEC1)?$/ SPEC1/' data
BEGIN value1 value2 value3 SPEC1
some_other_line1
BEGIN value1 value2 value3 value4 SPEC1
some_other_line2
BEGIN value1 value2 SPEC1
使用
sed
,您无法做得更好,因为不支持惰性量词。请注意,s|\(.*)\1 SPEC1|
与's |..*.&SPEC1|
或甚至's |$| SPEC1|
相比更好看,谢谢你提醒我&。谢谢@sundeep,谢谢你提醒。我删除了我的答案,因为我的答案似乎在网页中显示得不好。@yudongshen选择代码,然后单击{}
编辑按钮或使用ctrl+k
快捷方式。谢谢@Sundeep的清晰解释。我喜欢/SPEC1/!否定位:)第二个脚本不会将$
附加到字符串的末尾,如果它附加了$
,那么添加它时它仍然存在。它也会错误地匹配FOOSPEC1
,只需在$NF上做一个字符串比较(如果您非常想使用regexp,可以在两侧添加锚)。这是正确的方法。清晰、简单、健壮、高效、便携。。。。