Here is the example text:
abc_fgh
abc_edg_pkl
abc_plc
abc_action
there are some other texts in the file
not at begin abc_action
abc_nmp
How to replace the text begin with abc_ to efg_, and abc_action should not be modified?
That is to say, for the example text above, the output should be:
efg_fgh
efg_edg_pkl
efg_plc
abc_action
there are some other texts in the file
not at begin abc_action
efg_nmp
Every word begin with abc_ is not meaningful except abc_action, which should not be modified.
Every word begin with abc_ except abc_action should be modified to the word begin with efg_.
I can't guarantee that abc_ is at the begin of the line.
How to achieve this goal by sed or other command?
CodePudding user response:
sed '/^abc_action$/!s/^abc_/efg_/'
Which means *on lines not containing abc_actions and nothing else, replace the leading abc_ with efg_.
CodePudding user response:
- if you don't want to modify the line with
abc_action:
sed '/abc_action/!s/\([ ]\ \)abc_\|^abc_/\1efg_/g' filename
- if you want to modify the line with
abc_action, there is a trick to changeabc_actionto a special word or sign(here as#) which will not be replaced theabc_pattern, then modifyabc_pattern and recovery theabc_actionlast.
sed 's/abc_action/#/g' filename | sed 's/\([ ]\ \)abc_\|^abc_/\1efg_/g' | sed 's/#/abc_action/g'
explicate:
1, /abc_action/!: sed will not handle the lines which contain abc_action.
2, s/regexp/replacement/g: replace all regexp to replacement each line.
3, s/\([ ]\ \)abc_\|^abc_/\1efg_/g: will replace the word which start with abc_ or at the begin of the line as abc_ to efg_. I guess that the word which not at the begin of the line should be split by one or more blank.
4, \([ ]\ \): the one or more blank space pattern.
5, \1: will copy the pattern getting of the blank space in result.
CodePudding user response:
A Perl solution:
perl -lpe 's{abc_(?!action)}{efg_}g; ' in_file > out_file
The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-p : Loop over the input one line at a time, assigning it to $_ by default. Add print $_ after each loop iteration.
-l : Strip the input line separator ("\n" on *NIX by default) before executing the code in-line, and append it when printing.
(?!action) : negative lookahead. It means that the following string cannot match action.
The regex uses these modifier:
/g : Match the pattern repeatedly.
SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches
perldoc perlre: Perl regular expressions (regexes)
perldoc perlre: Perl regular expressions (regexes): Quantifiers; Character Classes and other Special Escapes; Assertions; Capture groups
perldoc perlrequick: Perl regular expressions quick start
