LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 01-15-2010, 10:52 AM   #1
Rudy
Member
 
Registered: Aug 2003
Location: United States
Distribution: Ubuntu 9.10, Red Hat
Posts: 49

Rep: Reputation: 15
Find & Replace string in multiple files


The title of my post says it all.

After hours (literally) of searching the web and reading man pages, I think I've come up with the following:

Code:
find . -exec grep 'path/to/file' -print | xargs -0 -I new_path mv {this is where I get confused}
So my code above is incomplete, obviously. In order to finish replacing the string, I need to mv the new file into the old file's spot. How do I do this, by incorporating it into my line of code?

And do I need to modify my code at all? Any thoughts, help, or suggestions would be appreciated.

- David

Last edited by Rudy; 01-15-2010 at 10:57 AM.
 
Old 01-15-2010, 11:08 AM   #2
affinity
Member
 
Registered: Nov 2009
Distribution: Slackware64
Posts: 132

Rep: Reputation: 20
Sed has a switch for editing files in place, its -i. This allows it to run the arguments on the file and make changes without having to create a copy and then later move the copy to the original. It also uses the -f switch to use commands from a file to be executed. A single sed command to replace one instance of text with another would look like this: sed -i 's:{target}:{new}:g' the :g tells sed to continue on replacing the first expression with the second until the end of file is reached, otherwise it would stop after the first occurrence. If you use multiple commands you would use -e before each one to let sed know that it's a new argument, otherwise it would treat it as part of the first argument.
 
1 members found this post helpful.
Old 01-15-2010, 11:16 AM   #3
Rudy
Member
 
Registered: Aug 2003
Location: United States
Distribution: Ubuntu 9.10, Red Hat
Posts: 49

Original Poster
Rep: Reputation: 15
ahh, the -i flag! Why did I not see that in my man page... oh well. I see it in there now.

So, when do the following, I get an error:
Code:
find . -exec grep 'path/to/file' -print | sed -i 's:/path/to/file:new/path/to/file:g'
The error is...
Code:
$ sed: no input files
$ find: missing argument to `-exec'
The command I am trying to execute is "grep" so why isn't that being translated by find as a command? Or am I doing something wrong? (obviously, I am, but what?)

Thanks again,
David

Last edited by Rudy; 01-15-2010 at 11:23 AM.
 
Old 01-15-2010, 11:39 AM   #4
affinity
Member
 
Registered: Nov 2009
Distribution: Slackware64
Posts: 132

Rep: Reputation: 20
For the sed part, you have to tell it what file is being altered after the arguments. It looks like you are trying to rename files though? If that's the case you will want to use the rename command instead. You wouldn't have to use grep to do this, using the example from the rename man page you would change the file extensions of any file with .htm to .html like this:
rename .htm .html *.htm

What exactly are you trying to do?
 
Old 01-15-2010, 11:47 AM   #5
Rudy
Member
 
Registered: Aug 2003
Location: United States
Distribution: Ubuntu 9.10, Red Hat
Posts: 49

Original Poster
Rep: Reputation: 15
Oops, poor choice of words in my SED example. Sorry about that.

Here's what I'm trying to do: I have file x, which contains string "y" and I want to change string "y" into string "z".
 
Old 01-15-2010, 12:05 PM   #6
affinity
Member
 
Registered: Nov 2009
Distribution: Slackware64
Posts: 132

Rep: Reputation: 20
Ok in that case you would simply do the following:
sed -i 's:y:z:g' x

To explain that line piece by piece:
-i for editing in place
s: means you are replacing text
y is the expression being changed
z is the replacement for y
g means global, continue until end
x is the file being altered.

If you are doing this on every file in a directory, and there are no hidden files, you can use * instead of a single filename. That will run the command on EVERY file, no exceptions. So only do that if you are positive it's what you want. If there are multiple files that you want to change, but they don't share a common naming scheme or are scattered about you can make this into a function so that you just type the function name followed by the filename. You would add the function to your ~/.bashrc like so:

function myscriptname {
FILE=$1 # where the first argument given after myscriptname is file
sed -i 's:y:z:g' $FILE
}

Then you could just type the following in your shell 'myscriptname file. This is also useful in that if you have multiple expressions you want replaced in the same file you simply add another sed command directly under the original, or any other types of commands you want done to that file.
 
Old 01-15-2010, 12:57 PM   #7
Rudy
Member
 
Registered: Aug 2003
Location: United States
Distribution: Ubuntu 9.10, Red Hat
Posts: 49

Original Poster
Rep: Reputation: 15
holy mackrell! That's it?

I just ran it, and that worked like a charm. I was trying to make things way too complicated here... thanks a ton.
 
Old 01-15-2010, 12:59 PM   #8
affinity
Member
 
Registered: Nov 2009
Distribution: Slackware64
Posts: 132

Rep: Reputation: 20
Quote:
Originally Posted by Rudy View Post
holy mackrell! That's it?

I just ran it, and that worked like a charm. I was trying to make things way too complicated here... thanks a ton.
Yea that's it, once you figure out the right tool for the job things are much easier . Your welcome!
 
Old 01-15-2010, 12:59 PM   #9
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Quote:
Originally Posted by Rudy View Post
I was trying to make things way too complicated here...
Sometimes I wonder if that's my raison d'etre.. It's very easy to over-complicate things (I know this from first-hand experience, but seem to need to relearn it regularly) by assuming something involves much more than it actually might. LOL.
 
Old 01-15-2010, 02:26 PM   #10
Rudy
Member
 
Registered: Aug 2003
Location: United States
Distribution: Ubuntu 9.10, Red Hat
Posts: 49

Original Poster
Rep: Reputation: 15
Well, I thought this had solved everything. Guess not.

Round 1 of replacements worked. Round 2? failed. Right now, I'm trying to replace a pretty complicated string. Here's my exact command:

Code:
sed -i 's.<img border="0" width="738" src="images/esa_logo.jpg" style="position: absolute; padding-left: 5px;" alt="Home" id="ESA logo"/>.<img border="0" width="738" src="images/esa_logo.jpg" style="position: relative; padding-left: 5px;" alt="Home" id="ESA logo"/>.g' *
And here's my error message:
Code:
sed: -e expression #1, char 131: unknown option to `s'
Any idea why?
 
Old 01-15-2010, 03:07 PM   #11
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
I haven't got my glasses on at this moment, but at a glance: since you're using a period as the sed special character, you probably need to escape the periods within the LHS and RHS of the expression. (such as .jpg should be \.jpg)

If this isn't it, I'll have another look after if nobody else has offered advice.

PS - use a special character that does not appear in the LHS or RHS,such as maybe a % sign, or @ sign.

Sasha

Last edited by GrapefruiTgirl; 01-15-2010 at 03:08 PM.
 
Old 01-15-2010, 10:40 PM   #12
affinity
Member
 
Registered: Nov 2009
Distribution: Slackware64
Posts: 132

Rep: Reputation: 20
Take a look at this site, it's a quick run through of using sed. I linked to the section about delimiters.
 
Old 01-16-2010, 07:14 AM   #13
H_TeXMeX_H
LQ Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301
Try

Code:
sed -i 's|<img border="0" width="738" src="images/esa_logo.jpg" style="position: absolute; padding-left: 5px;" alt="Home" id="ESA logo"/>|<img border="0" width="738" src="images/esa_logo.jpg" style="position: relative; padding-left: 5px;" alt="Home" id="ESA logo"/>|g' *
 
Old 04-15-2010, 07:49 AM   #14
Maskkkk
LQ Newbie
 
Registered: Sep 2004
Posts: 4

Rep: Reputation: 0
I've been looking at this thread, now say I wanna do the same thing as Rudy only I want to do it recursively on all of the files in a certain directory.

Here is what I've got so far:

Code:
find . "*.js" -exec sed -i s/jstestdriver\.console\.log.*;//g ;
But then I get the error:

Code:
sed: no input files
 
Old 04-15-2010, 08:10 AM   #15
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Maskkkk View Post
I've been looking at this thread, now say I wanna do the same thing as Rudy only I want to do it recursively on all of the files in a certain directory.

Here is what I've got so far:

Code:
find . "*.js" -exec sed -i s/jstestdriver\.console\.log.*;//g ;
But then I get the error:

Code:
sed: no input files
You need find's special symbol "{}" (without the quotes) which find replaces with the found file name and you need to escape the ";" or it is seen by the shell as a command terminator
Code:
find . "*.js" -exec sed -i s/jstestdriver\.console\.log.*;//g {} \;
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Find and replace string Johng Programming 9 01-13-2010 04:50 AM
search and replace string having multiple special characters say_hi_ravi Linux - Newbie 4 08-26-2009 07:43 AM
Linux command to find and replace string within text file chips11 Linux - Newbie 5 11-24-2008 02:25 PM
how to find and replace only the 2nd occurrence of similar string in a file hchoonbeng Linux - Newbie 1 10-08-2008 03:44 AM
Simple find&replace across 100 files saphil Linux - Newbie 2 01-03-2008 12:21 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 03:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration