sed -s substitute

Introduction

To use the sed substitute command you need the 's' option

The general syntax looks like this:

sed '[range] s/<string>/<replacement>/' file

Translation

sed ' [range] s/<string>/<replacement>/' file

range is the area in which the replacement is to be made. It is set via a condition. It must always be inside / /

string is the set of characters that needs to be replaced

replacement is the set of characters that string is replaced with

file is the name of the file (optionally with the path to the file) in which this replacement will be made

Replacing a word in a file

SED is usually applied to files, for example to logs or configs.

Suppose we have a file input.txt with the following content

Here is a String Here is an Integer Here is a Float

We want to replace the word Here with There

sed 's/Here/There/' input.txt

The result will be printed to the console:

There is a String

There is an Integer

There is a Float

If you need to change the content of the file instead of printing it to the console (to stdout), use the option -i

sed -i 's/Here/There/' input.txt

In this case the source file will be overwritten input.txt

It is considered good practice to first test your script without -i and, if everything works correctly, make the changes to the file.

With -i.bak you can create a reserve file (a backup)

Let us look at a more complicated example.

Suppose the file input.txt now looks like this:

Here is an Apple. Here is a Pen. Here is an ApplePen Integer is Here Here is a Float Here is a Pen. Here is a Pineapple. Here is a PineapplePen

sed 's/Here/There/' input.txt

As you will now see, the replacement will happen only once per line

There is an Apple. Here is a Pen. Here is an ApplePen

Integer is There

There is a Float

There is a Pen. Here is a Pineapple. Here is a PineapplePen

To replace all the words you need the g option

sed 's/Here/There/g' input.txt

There is an Apple. There is a Pen. There is an ApplePen
Integer is There

There is a Float

There is a Pen. There is a Pineapple. There is a PineapplePen

ApplePen

Replacing a word in a file and writing the result to another file

The same replacement, but with the output to a new text file, which we will call output:

sed 's/Here/There/' input.txt > output.txt

Replacing a word in several files at once

If you need to process several files at once: for example the file 1.txt with the content

First File: Here

And the file 2.txt with the content

Second File: Here

This can be done using *.txt

sed 's/Here/There/' *.txt > output.txt

The output file output.txt will look like this

First File: There Second File: There

Replacing only in specific lines

Consider the file input.txt

cat input.txt

lex red red test red muha lex red red lex red lex blue

Let us replace red with yellow, but not everywhere, only where the line starts with lex

sed -i '/^lex/ s/red/yellow/' input.txt

cat input.txt

lex yellow red test red muha lex red red lex yellow lex blue

/^lex/ - the replacement must be done only in those lines that start with lex - this is how we set range

g

If you do not set range as in the previous example ,then in every line the first red will be replaced with yellow

sed -i 's/red/yellow/' input.txt

cat input.txt

lex yellow yellow test yellow muha lex yellow red lex yellow lex blue

To replace absolutely all red with yellow, you need to add the option g (greed - greediness)

sed -i 's/red/yellow/g' input.txt

cat input.txt

lex yellow yellow test yellow muha lex yellow yellow lex yellow lex blue

Adding indentation

Consider the script script.sh

nl -ba script.sh

1 #!/bin/bash 2 3 i=0 4 while [ $i -le 3 ] 5 do 6 echo "i= " 7 echo $i 8 (( i++ )) 9 done

If you decide to add indentation inside do … done : that is, shift, say, the text in lines 6, 7 and 8 by four spaces - run

sed -i ' 6,8 s/^/    /g' script.sh

nl -ba script.sh

1 #!/bin/bash 2 3 i=0 4 while [ $i -le 3 ] 5 do 6 echo "i= " 7 echo $i 8 (( i++ )) 9 done

I warn you that if your script has empty lines, nl will not count them but sed will - that is why I used nl with the ba options

If you do not need to make changes to the source file, you can use

sed -n ' 6,8 s/^/    /p' script.sh

echo "i= " echo $i (( i++ ))

Replace empty lines

Replace all empty lines with double line-break tags

$ sed 's/^[[:space:]]*$/\<br\>\<br\>/' input.txt > output.txt

Replace the beginning of a line

Consider the file input.txt

cat input.txt

lex red red test red muha lex red red lex red lex blue

The beginning of a line is indicated by the ^ character

Let us replace red with yellow, but not everywhere, only where the line starts with lex

sed -i '/^lex/ s/red/yellow/' input.txt

cat input.txt

lex yellow red test red muha lex red red lex yellow lex blue

Changing a value in a JSON file

Consider the file sample.json in which SpamBlocking needs to be replaced with true by default

{ "websites": { "AppUpdateURL": "", "BlockAddons": true, "EncryptedExtensions": { "Enabled": true, "Locked": true }, "SpamBlocking": { "Default": false }, "Permissions": { "Camera": { "BlockRequests": true }, "Location": { "BlockRequests": true }, "Microphone": { "BlockRequests": true }, "Popups": { "BlockRequests": true } } } }

If the value SpamBlocking occurs in the JSON file only once, the following script will do j.sh

# www.eth1.ru FILENAME=sample.json PATTERN=SpamBlocking # Find line number of the PATTERN PREVLINE=$(sed -n /$PATTERN/= ./$FILENAME) # Calculate line with value LINE=$(( $PREVLINE + 1 )) # Replace sed -i $LINE's@false@true@' ./$FILENAME

./j.sh

You can check the result with grep

grep -A1 SpamBlocking sample.json

"SpamBlocking": { "Default": true

Working with spaces in Windows paths

If you need to use sed in Windows you need to take into account the possible presence of spaces in the paths.

Suppose the settings of the software are in the files Studio.exe.config , Loader.exe.config Tool.exe.config in the directory

C:\Program Files\My Win Software

Or if you open through Git Bash

/c/Program Files/My Win Software

and its subdirectories net48. The line where the log level is set contains <variable name="logLevel"

The goal is to change the log level from Erorr to Debug

WD=/c/Program\ Files/My\ Win\ Software S="$WD/Studio.exe.config" L="$WD/Loader.exe.config" T="$WD/net48/Tool.exe.config" /usr/bin/sed.exe -i '/<variable name="logLevel"/ s/Error/Debug/' "$S" "$L" "$T"

Article author: Andrei Olegovich