LinuxBasics.org

The community that helps people to run Linux

rss

Recursive search and replace

Search and replace a string in many files at once. Sombody wrote on a mailing-list:

[…]
In windows I had my favorite text editor notetab. I could open all *.php in a dir and do a find and replace and then save all. How can I do this in Linux?

With a combination of bash, find and perl :)

For our example I want to change the include path in an Open source php program to a more secure path above the web directories root. Just in case php should crash and all the password info in the include file could be read during this time. In my example I have a dir called: my_examplephpscript It has a few sub directories as well. I want to recursively search in all *.php files,

Let’s first find all files we want. I do not want to trash anything, so I look for *.tmp instead of *.php. You can adjust the example.

stw@laptop:~> find . -iname '*.tmp' -print

find starts in the current directory (that’s the dot) and looks for files that match ‘*.tmp’, case-insensitive (-iname). It prints the names (-print, could be omited since it is the default action). Let’s see some action:

stw@laptop:~> find . -iname '*.tmp' -print
./HPS/Buero privat/LISTEN/Etiketten/ZDP24071.TMP
./nscopy.tmp
./nscopy-1.tmp
./nscopy-2.tmp
./nscopy-3.tmp
./nscopy-4.tmp
./nscopy-5.tmp
./nscopy-6.tmp
./nscopy-7.tmp
./nscopy-8.tmp
./nscopy-9.tmp

Next we want to tell find to execute another command for each file that it finds. We replace the “-print by -exec”. {} is substituted by the filename and a semicolon marks the end of the command. We need to escape the semicolon in bash.

stw@laptop:~> find . -iname '*.tmp' -exec ls -i {} \;
179903 ./HPS/Buero privat/LISTEN/Etiketten/ZDP24071.TMP
1684407 ./nscopy.tmp
1684410 ./nscopy-1.tmp
1684412 ./nscopy-2.tmp
1684414 ./nscopy-3.tmp
1684418 ./nscopy-4.tmp
1684422 ./nscopy-5.tmp
1684424 ./nscopy-6.tmp
1684426 ./nscopy-7.tmp
1684428 ./nscopy-8.tmp
1684430 ./nscopy-9.tmp

for all text that matches /include/config.php and replace with ../include/config.php

Perl can do the search and replace. It can do so with a one-liner (read: from the commandline w/o writing a ‘real’ program).

perl -i.DontBlameStW -pe "s/oldstring/newstring/g" filename

‘perl’ will do the replacing in place (-i) making a backup with the extension .DontBlameStW by executing (-e) the search&replace command “s/oldstring/newstring/g” as long as there is something to be searched (-p) in the file (filename)

stw@laptop:~> echo >test.tmp "This is a test of Perl. Perl testing brings out the pearls in perl. Larry Wall has guidelines how to capitalize [Pp]erl. To sum them up: Larry has created perl to interpret Perl."
stw@laptop:~> cat test.tmp
This is a test of Perl. Perl testing brings out the pearls in perl. Larry Wall has guidelines how to capitalize [Pp]erl. To sum them up: Larry has created perl to interpret Perl.
stw@laptop:~> perl -i.DontBlameStW -pe "s/Perl/PHP/g" test.tmp
stw@laptop:~> cat test.tmp
This is a test of PHP. PHP testing brings out the pearls in perl. Larry Wall has guidelines how to capitalize [Pp]erl. To sum them up: Larry has created perl to interpret PHP.
stw@laptop:~> cat test.tmp.DontBlameStW
This is a test of Perl. Perl testing brings out the pearls in perl. Larry Wall has guidelines how to capitalize [Pp]erl. To sum them up: Larry has created perl to interpret Perl.

(this will allow me to place the include file above webroot for security) Just how can I accomplish this task?

Combine the two:

find . -iname '*.tmp' -exec perl -i.DontBlameStW -pe "s/Perl/PHP/g" {} \; (That is one line!)

Thanks

You are welcome.


Created by stwaidele


Copyright (c) by the authors.
Prior to editing, authors agreed to license their contributions by the terms of the GPL.
See our licensing page for details.


Linux® is a registered trademark of Linus Torvalds.


 
  tutorials/advanced/realworld/recursive_search_and_replace.txt · Last modified: 2008/07/20 19:08

LinuxBasics.org

Start Linux-Course Tutorials Linux Links Security Blog Forum E-mail List Search Online Chat

Site-Info

Help Get in Touch Making of LBo

Wiki-Control

Powered by

Linux Apache DokuWiki Mailman RUTE ht://Dig