How Do I Replace A Text String In Many Files At Once?

The replace command is a string-replacement utility. It changes strings in place in files or on the standard input. This command uses a finite state machine to match longer strings first. It can be used to swap strings. This command is similar to the Perl -pie syntax or sed (stream editor) command.

Please note that the replace command is part of is MySQL database system. If you don’t have MySQL installed, you don’t have replace command.

ADVERTISEMENTS

Syntax

replace OLD-STRING NEW-STRING < INPUT-FILE > OUTPUT-FILE

Examples

To replace all occurrences of word UNIX with Linux, enter:
$ replace UNIX Linux < oldfile > newfile

The replace command can be used in a pipeline, run:
$ cat /etc/passwd | replace : '|'

You can skip the cat command, enter:
$ replace : '|' < /etc/passwd

It also supports few special characters in string replacement:

  • \^ : Match start of line.
  • $ : Match end of line.

How Do I Update All *.txt Files At Once?

You use bash for loop as follows:

#!/bin/bash
for f in /path/to/*.txt
do
   replace UNIX Linux < "$f" > "$f.new"
done

The replace command does not understand regular expression. To use regular expression try the sed command or Perl.

Sed Command Example

To replace all occurrences of word UNIX with Linux using the sed command, enter:

sed 's/UNIX/Linux/g' < input.file > output.file

OR

sed -i 's/UNIX/Linux/g' input.file

OR use bash shell for loop as follows to update all *.doc files at once:

#!/bin/bash
for f in /path/to/*.doc
do
   sed -i  's/UNIX/Linux/g' "$f"
done

Updated for accuracy!

🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source & DevOps topics via:
CategoryList of Unix and Linux commands
File Managementcat
FirewallCentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNCentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
21 comments… add one
  • Joe Nov 12, 2005 @ 23:30

    To use perl, just remember Perl Pie!

    perl -p -i -e ‘s/hello/goodbye/g’ textfile.txt

  • LinuxTitli Nov 12, 2005 @ 23:47

    Joe, very nice. Your tip sound yummy 🙂 thanks for sharing with us

  • Anonymous Nov 30, 2005 @ 9:34

    http://www.debian-administration.org/articles/298 has a fine article and discussion on Perl Pie.

  • Anonymous Dec 12, 2005 @ 0:13

    what about this line:

    perl -p -i -e ‘s/|00000000.00|/||/g’ myfile.txt

    I want to replace |00000000.00| with ||

    I get a compilation error.

  • 🐧 nixcraft Dec 12, 2005 @ 1:41

    You need to write it as follows:

    perl -p -i -e ‘s/|00000000.00|/||/g’ myfile.txt

    || got some special meaning (regex) | will disable it

  • Anonymous Dec 12, 2005 @ 21:02

    This does the trick perfectly! Thanks for sharing this special character technique nixcraft!

  • walter Aug 9, 2007 @ 6:59

    or try this…
    first make a bash script, ‘fixer.sh’


    #!/bin/bash
    replace CHANGEFROM CHANGETO $1.tmp
    rm $1
    mv $1.tmp $1

    now run this command line…

    $ grep CHANGEFROM |cut -d':' -f1 |xargs -n 1 fixer.sh

    the results is that all files in the directory (or whatever you grep for) will be changed automagically.

    just make sure the grep doesn’t include the fixer script itself, or it will die half-way through changing when execute permissions are reset!

    😉

  • Raj Apr 10, 2008 @ 13:25

    thanks for sharing this info

  • lefty.crupps Jun 16, 2008 @ 16:28

    Am I the only one who sees no difference in these?

    >> perl -p -i -e ’s/|00000000.00|/||/g’ myfile.txt
    >> I want to replace |00000000.00| with ||
    >> I get a compilation error.

    — —
    >> You need to write it as follows:
    >> perl -p -i -e ’s/|00000000.00|/||/g’ myfile.txt

  • Eden Feb 11, 2009 @ 0:21

    Cant see the diference… 🙁

  • 2046 Mar 31, 2009 @ 18:09

    find ./* -type f -exec sed -i 's///g' {} ;

  • Matthew Scott Jul 18, 2010 @ 3:43

    `replace`

  • Matthew Scott Jul 18, 2010 @ 3:46

    `replace` can work with files, which may be simpler than writing a shell script as mentioned above. It will even convert files in place. Say you want to change an instance of ‘foo’ to ‘bar’ in all files in a certain directory, recursively. In bash,

    for i in `grep -lR foo dir/to/files`; do replace foo bar — $i; done

    Simply put, use two dashes to separate filenames from the from/to strings, and it’ll convert the files.

  • DougTheBug Aug 17, 2010 @ 22:07

    I couldn’t even find this command in Ubunto 10.04 (or in repositories). I ended up using rpl instead. Is really fun for databending images.

  • Ben Mar 7, 2011 @ 4:23

    ‘Replace’ is found in mySQL. If you don’t have mySQL, you don’t have `replace`

  • saravanan Jan 4, 2012 @ 14:35

    I want to replace a string in sub directories also(in Linux), is there any specific command for that?

  • Jay Mar 23, 2012 @ 17:54

    hi,
    thanks for the info..nice script. just wanted to add that when i used to ‘for’ loop version w/ ‘sed’ command (in Linux) it would read all the “*.sh” files that i wanted to substitue a string but did not actually make the change. just an fyi, i removed the single quote (‘) in the sed line and it works.

    See below:
    #!/bin/bash
    for f in /path/to/*.doc
    do
    sed -i s/UNIX/Linux/g “$f”
    done

    Thanks

  • SAURABH SHARMA Apr 1, 2012 @ 7:04

    for i in `find . -type f`
    do
    j=`echo $i|sed ‘s/$1/$2/g’`
    mv $i $j
    done;

  • Nathan Apr 20, 2012 @ 0:28

    I noticed in my bash shell I need to do the following on my Mac:

    sed -i ” ‘s/UNIX/Linux/g’ input.file

    Otherwise I get stdin error.

  • drankinatty Apr 5, 2013 @ 17:37

    Your example below will fail on filenames containing spaces due to the default internal field separator (IFS) breaking on a space character (default=$’ tn’):

    #!/bin/bash
    for f in /path/to/*.txt
    do
       replace UNIX Linux  "$f.new"
    done
    

    To properly handle filenames with spaces, you should set IFS to break on new lines only:

    #!/bin/bash
    oldIFS=IFS
    IFS=$'n'
    for f in /path/to/*.txt
    do
       replace UNIX Linux  "$f.new"
    done
    IFS=oldIFS

    You can also simply run the command in a subshell by enclosing it in parenthesis and not have to worry about resetting IFS at the completion of the loop. Eg.:

    (IFS=$'n'; for f in /path/to/*.txt; do replace UNIX Linux  "$f.new"; done)

    However, while replace is a valid solution, I have found sed to be the most robust and much faster than perl for large search and replace tasks.

  • asdds Jun 17, 2013 @ 13:11

    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.