Find and replace text within a file using commands
sed -i 's/original/new/g' file.txt
Explanation:
sed
= Stream EDitor-i
= in-place (i.e. save back to the original file)The command string:
s
= the substitute commandoriginal
= a regular expression describing the word to replace (or just the word itself)new
= the text to replace it withg
= global (i.e. replace all and not just the first occurrence)
file.txt
= the file name
There's multitude of ways to achieve it. Depending on the complexity of what one tries to achieve with string replacement, and depending on tools with which user is familiar, some methods may be preferred more than others.
In this answer I am using simple input.txt
file, which you can use to test all examples provided here. The file contents:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
BASH
Bash isn't really meant for text processing, but simple substitutions can be done via parameter expansion , in particular here we can use simple structure ${parameter/old_string/new_string}
.
#!/bin/bash
while IFS= read -r line
do
case "$line" in
*blue*) printf "%s\n" "${line/blue/azure}" ;;
*) printf "%s\n" "$line" ;;
esac
done < input.txt
This small script doesn't do in-place replacement, meaning that you would have to save new text to new file, and get rid of the old file, or mv new.txt old.txt
Side note: if you're curious about why while IFS= read -r ; do ... done < input.txt
is used, it's basically shell's way of reading file line by line. See this for reference.
AWK
AWK, being a text processing utility, is quite appropriate for such task. It can do simple replacements and much more advanced ones based on regular expressions. It provides two functions: sub()
and gsub()
. The first one only replaces only the first occurrence, while the second - replaces occurrences in whole string. For instance, if we have string one potato two potato
, this would be the result:
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana
$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'
one banana two potato
AWK can take an input file as argument, so doing same things with input.txt
, would be easy:
awk '{sub(/blue/,"azure")}1' input.txt
Depending on the version of AWK you have, it may or may not have in-place editing, hence the usual practice is save and replace new text. For instance something like this:
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
SED
Sed is a line editor. It also uses regular expressions, but for simple substitutions it's sufficient to do:
sed 's/blue/azure/' input.txt
What's good about this tool is that it has in-place editing, which you can enable with -i
flag.
Perl
Perl is another tool which is often used for text processing, but it's a general purpose language, and is used in networking, system administration, desktop apps, and many other places. It borrowed a lot of concepts/features from other languages such as C,sed,awk, and others. Simple substitution can be done as so:
perl -pe 's/blue/azure/' input.txt
Like sed, perl also has the -i flag.
Python
This language is very versatile and is also used in a wide variety of applications. It has a lot of functions for working with strings, among which is replace()
, so if you have variable like var="Hello World"
, you could do var.replace("Hello","Good Morning")
Simple way to read file and replace string in it would be as so:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
With Python, however, you also need to output to new file , which you can also do from within the script itself. For instance, here's a simple one:
#!/usr/bin/env python
import sys
import os
import tempfile
tmp=tempfile.mkstemp()
with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
for line in fd1:
line = line.replace('blue','azure')
fd2.write(line)
os.rename(tmp[1],sys.argv[1])
This script is to be called with input.txt
as command-line argument. The exact command to run python script with command-line argument would be
$ ./myscript.py input.txt
or
$ python ./myscript.py input.txt
Of course, make sure that ./myscript.py
is in your current working directory and for the first way, ensure it is set executable with chmod +x ./myscript.py
Python can also have regular expressions , in particular, there's re
module, which has re.sub()
function, which can be used for more advanced replacements.
There are a number of different ways to do this. One is using sed
and Regex. SED is a Stream Editor for filtering and transforming text. One example is as follows:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog
Another way which may make more sense than < strin
and > strout
is with pipes!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai
The quick brown fox jumped over the lazy sleeping dog