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_action
to a special word or sign(here as#
) which will not be replaced theabc_
pattern, then modifyabc_
pattern and recovery theabc_action
last.
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