Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace only if string exists in current line

Tags:

linux

shell

sed

I have a line such as:

sed -i 's/mystring/newstring/' $target

This command will change all mystring to newstring.

What I want now is: when the program sees mystring, how can I check for the current line if the string searchstring exists or not? If it exists, newstring is 1; otherwise, newstring is 0.

like image 432
Anders Lind Avatar asked Aug 14 '12 18:08

Anders Lind


2 Answers

Solution

Assuming your input file $target contains the following:

some text mystring some other text
some text mystring a searchstring
just some more text

This command:

sed -i -e '/searchstring/ s/mystring/1/ ; /searchstring/! s/mystring/0/' $target

will change its content to:

some text 0 some other text
some text 1 a searchstring
just some more text

Explanation

The script contains two substitute (s) commands separated by a semicolon.

The substitute command accepts an optional address range that select which lines the substitution should take place.

In this case regexp address was used to select lines containing the searchstring for the first command; and the lines that do not contain the searchstring (note the exclamation mark after the regexp negating the match) for the second one.

Edit

This command will perform better and produce just the same result:

sed -i -e '/searchstring/ s/mystring/1/ ; s/mystring/0/' $target

The point is that commands are executed sequentially and thus if there is still a mystring substring in the current line after the first command finished then there is no searchstring in it for sure.

Kudos to user946850.

like image 125
Ihor Kaharlichenko Avatar answered Nov 15 '22 20:11

Ihor Kaharlichenko


This is from the sed one-liners page:

OPTIMIZING FOR SPEED: If execution speed needs to be increased (due to large input files or slow processors or hard disks), substitution will be executed more quickly if the "find" expression is specified before giving the "s/.../.../" instruction. Thus:

sed 's/foo/bar/g' filename         # standard replace command
sed '/foo/ s/foo/bar/g' filename   # executes more quickly
sed '/foo/ s//bar/g' filename      # shorthand sed syntax

Speed is not the issue of the question at hand, but the syntax hints help formulating the solution:

sed -i '/searchstring/ s/mystring/1/; s/mystring/0/' $target
like image 35
krlmlr Avatar answered Nov 15 '22 21:11

krlmlr