Regex 如何将文本替换为不包含同一行的特定字符串?

Regex 如何将文本替换为不包含同一行的特定字符串?,regex,bash,sed,Regex,Bash,Sed,输入文本文件:file.txt AAA BBB_CCC BBB AAA BBB 需要获得: AAA_CCC BBB_CCC BBB_CCC AAA_CCC BBB_CCC 我使用以下regexp调用sed: sed "/_CCC/! s/AAA/AAA_CCC/g;/_CCC/! s/BBB/BBB_CCC/g" file.txt > file_out.txt 但它产生了: AAA_CCC BBB_CCC BBB_CCC AAA_CCC BBB 一种解决方案是在同一个文件上调用se

输入文本文件:file.txt

AAA
BBB_CCC
BBB
AAA BBB
需要获得:

AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB_CCC
我使用以下regexp调用sed:

sed "/_CCC/! s/AAA/AAA_CCC/g;/_CCC/! s/BBB/BBB_CCC/g" file.txt > file_out.txt
但它产生了:

AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB

一种解决方案是在同一个文件上调用sed两次,但我认为存在一种更优雅的方式。

awk
解决方案将
\u CCC
附加到每个不包含它的字段:

awk '{ for(i=1; i<=NF; i++) if( $i !~ /_CCC$/ ) $i = $i"_CCC"; }1' file

#output:
AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB_CCC

awk'{for(i=1;i一种方法是系统地覆盖
\u CCC
,如果它存在:

sed 's/\(AAA\|BBB\)\(_CCC\)\?/\1_CCC/g' file
使用ERE:

sed -E 's/(AAA|BBB)(_CCC)?/\1_CCC/g' file

一个在精神上与您相近的解决方案:

$ sed -E '/_CCC/!s/(AAA|BBB)/\1_CCC/g' infile
AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB_CCC

您的解决方案失败,因为在最后一行插入
\u CCC
后,
/\u CCC/!
检查失败:字符串现在仍然存在。我的解决方案只需使用一个替换命令即可避免该问题。

另一个
awk

$ awk -v RS=' +|\n' '{sub("(_CCC|)$","_CCC"); ORS=RT}1' file

AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB_CCC

另一个sed解决方案:

$ sed 's/\(_CCC\)*\( \|$\)/_CCC\2/g' file
AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB_CCC

您想将
\u CCC
附加到每个字段还是仅附加到字段
AAA
BBB
?换句话说,如果您有字段
DDD
,或者如果您有字段
BBB\u CCC\BBB
,该怎么办?