Solved

Replacing a string in multiple files?

Posted on 2004-08-05
10
612 Views
Last Modified: 2010-04-21
Hi,
This is my first EE question. I've searched the Linux TA's before asking, but maybe I haven't been searching the right term, because I haven't come across anything that has helped me yet.

Basically, I need to edit a string in several webpages on several different domains, and doing this manually is very time consuming. I'm wanting a shell script to run that will search all the files in a directory, find the old string and replace it with the new string. I'm fairly new to linux and shell scripting, obviously, so please explain your solution so I can learn from your expertise as well as solve my immediate problem.

Thanks in advance. Love the site so far. I found it a week ago, and have learned a lot just from searching various topics...
0
Comment
Question by:heresy_is_progress
  • 4
  • 4
  • 2
10 Comments
 
LVL 36

Accepted Solution

by:
grblades earned 300 total points
ID: 11729382
Hi heresy_is_progress,
'sed' is a very usefull utility which will perform various edititing functions. One of which is a search and replace. Here is a quick example. I haven't tested it myself.

#!/bin/bash
allfiles=`ls -1`;
for file in $allfiles ; do
sed -e s/originaltext/replacewith/ $file > /tmp/tempfile
rm -f $file
mv /tmp/tempfile $file
done
0
 

Author Comment

by:heresy_is_progress
ID: 11729584
grblades,
Thanks for the prompt reply. I'm assuming I'll need to run this script from the directory that I'm editing, since there isn't anyewhere that tells it what directory to look for? if so, that isn't a problem; I just wanted to clarify before testing... thanks...
0
 
LVL 36

Expert Comment

by:grblades
ID: 11729647
Yes it works in the current directory.
0
 

Author Comment

by:heresy_is_progress
ID: 11729748
Awesome! it works. Another question, then you get the points:
can I define a variable to the newstring & oldstring? for example

#!/bin/bash
oldstring = '/path/to/oldfile/oldfile'
newstring = '/path/to/newfile/newfile'

allfiles=`ls -1`;
for file in $allfiles ; do
sed -e s/$oldstring/$newstring/ $file > /tmp/tempfile
rm -f $file
mv /tmp/tempfile $file
done

if that is do-able, is my syntax correct? thanks...
0
 
LVL 36

Expert Comment

by:grblades
ID: 11729834
I don't follow what you mean. Do you want to take the original string and the string to replace it with from a couple of text files?
If you do then you are almost correct but remember that the ` symbol evaluates the command so if you want to pull the contents of a file into a variable you have to do :-

oldstring = 'cat /path/to/oldfile/oldfile'
newstring = 'cat /path/to/newfile/newfile'

Note that sed is using the '/' character to separate parameters so the search or replace string cannot contain them. Or at least if it does you need to escape them.
The search string is also a regular expression (see man grep for some infor on regular expressions) so matching 192.168.1.2 will find 192.168.1.2 and 192.168.102 (since the . matches any character).
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:heresy_is_progress
ID: 11729935
actually, I'm wanting to edit an absolute filepath that's calling up an obsolete include file in a php page. on the actual php script, I'm wanting to change:

include '/old/path/to/includefile';

to

include '/new/path/to/includefile';

so yes, I need to escape the forward slashes(/). What character do I use, a backslash(\)?
0
 
LVL 36

Expert Comment

by:grblades
ID: 11730118
Yes you use a backslash. I think you might need quotes around the expression also.

So:-
sed -e "s/\/old\/path\/to\/includefile/\/new\/path\/to\/includefile/" $file > /tmp/tempfile

regular expressions can get very complicated to look at quite quickly ;)
0
 

Author Comment

by:heresy_is_progress
ID: 11730416


"sed -e "s/\/old\/path\/to\/includefile/\/new\/path\/to\/includefile/" $file > /tmp/tempfile

regular expressions can get very complicated to look at quite quickly ;)"

I'll say. What are all those "'N's" and "V's"? jk...;-D

thanks grblades. I threw on a 50 point bonus for all your help...:-)
0
 

Expert Comment

by:miyako
ID: 12211846
I know this is closed, but the following script eliminates having to worry about the regular expression handling.  Since it uses $ substitution, your search and replace strings will not be treated as regexps.  So, you can safely include any characters, except you must "escape" the $ character with a backslash, otherwise it is considered a variable.

You can call this from the command line specifying the parameters, so there's no need to edit the script each time.  Have fun...

Note that in the unlikely event that you already have files named *.greplace, they will be deleted, since greplace uses them as the temporary file.  I could rewrite it with tmpfile....

#!/bin/bash
#
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ] ; then
      echo
      echo "greplace performs a global search and replace on multiple files, recursing directories."
      echo
      echo "USAGE: greplace path filename_pattern search_string replace_string"
      echo "WHERE:"
      echo "        path : path to start search (greplace always recurses)"
      echo "        filename_pattern : pattern of filenames to search - ALWAYS enclose in quotes"
      echo "        search_string : string to search for (ALWAYS enclose in quotes, if it contains '\$' be sure to preceed with backslash."
      echo "        replace_string : string to replace search_string with (ALWAYS enclose in quotes, if it contains '\$' be sure to preceed with backslash."
      exit 192
fi

ALLFILES=`grep -l --directories=recurse --exclude=*~ --include="$2" "$3" "$1"`
echo "Replacing $3 with $4"
for FILE in $ALLFILES ; do
      echo "Processing ${FILE}..."
      rm ${FILE}.greplace &> /dev/null
      touch ${FILE}.greplace
      exec 3< "$FILE"
      while read THISLINE <&3 ; do
            echo "${THISLINE//$3/$4}" >> $FILE.greplace
      done
      exec 3>&-
      mv $FILE ${FILE}~
      mv $FILE.greplace $FILE
done
0
 

Expert Comment

by:miyako
ID: 12211858
Oh yeah...forward slashes need to be escaped as well...
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
script that sorts the lines in file according to integer in line 7 26
File system unmounted 3 155
Ubuntu 16.04 Emergency Boot 2 169
Help with a backup script in Linux 4 75
The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now