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
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