Home > Mobile >  How to achieve this replacement by `sed` or other command?
How to achieve this replacement by `sed` or other command?

Time:05-13

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 change abc_action to a special word or sign(here as #) which will not be replaced the abc_ pattern, then modify abc_ pattern and recovery the abc_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

  • Related