CODIJY
CODIJY

Reputation: 93

How to replace the text with not containing specific string with the same line?

Input text file: file.txt

AAA
BBB_CCC
BBB
AAA BBB

Need to get:

AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB_CCC

I call the sed with following regexp:

sed "/_CCC/! s/AAA/AAA_CCC/g;/_CCC/! s/BBB/BBB_CCC/g" file.txt > file_out.txt

But it produces:

AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB

One solution is calling sed twice on the same file, but I think there exists a more elegant way.

Upvotes: 0

Views: 88

Answers (5)

James Brown
James Brown

Reputation: 37404

Yet another sed solution:

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

Upvotes: 0

karakfa
karakfa

Reputation: 67497

another awk

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

AAA_CCC
BBB_CCC
BBB_CCC
AAA_CCC BBB_CCC

Upvotes: 2

PesaThe
PesaThe

Reputation: 7499

awk solution that will append _CCC to every field that doesn't contain it:

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

Upvotes: 2

Benjamin W.
Benjamin W.

Reputation: 52132

A solution that's close to yours in spirit:

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

Your solution fails because after inserting _CCC on the last line, the /_CCC/! check fails: the string is now there after all. My solution avoids that problem by using just a single substitution command.

Upvotes: 2

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

One way consists to overwrite _CCC systematically if it exists:

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

Using ERE:

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

Upvotes: 4

Related Questions