Web Hosting Talk







View Full Version : linux command-line search and replace tool needed.


Domenico
02-05-2002, 09:26 AM
Hello,

I'm looking for a linux command-line search and replace tool (for remote use through ssh) that replaces a FAULTY string in a html file wich is the same in more than 200 different directories on one server (copied from a faulty file in the skeleton dir).

I just found out and now I need to replace it :(

Wich utility can I use for this?

Thank you,
Domenico

allan
02-05-2002, 09:59 AM
Are you looking for something to replace a string within the file, or change the file name?

If it is to change multiple filenames, I have a utility called frename on my site, that might be useful:

http://www.allan.org/scripts/rename/

If you are trying to change information within a file, you can do this from the command line using perl:



perl -pi.bak -e "s/string1/string2/g" *.html



The only problem is, I am not sure if it can be made to work recursively to cover all the directories you need.

Domenico
02-05-2002, 10:09 AM
Hi uuallan,

A string within the same file in many different directories has to be changed so it has to look into the directories.

/home/MORE THAN 200 DIFFERENT DIRECTORIS/index.shtml

A string within index.shtml has to be changed in all those directories.

ScottD
02-05-2002, 10:12 AM
To recursively execute:

find . -name index.shtml -exec perl -pi.bak -e "s/string1/string2/g" {} \;

There are probably even easier ways.

allan
02-05-2002, 10:26 AM
Diz --

That should do it, I tested it on my system and was able to recursively execute through 4 directory levels and change text within the files:



find /home -name *.shtml -exec perl -pi.bak -e "s/string1/string2/g" {} \;



You are right, I am sure there may be easier ways to do it, but for a one time shot it is not too bad :)

Domenico
02-05-2002, 10:53 AM
Hmm, thanks for helping guys but maybe I must tell what the strings are.

I tried this:
root@host [/home]# find . -name index.shtml -exec perl -pi.bak -e "s/file:///C|/Work/voorwaarden.php//voorwaarden.php/g" {} \;
Bareword found where operator expected at -e line 1, near "/Work/voorwaarden"
(Missing operator before voorwaarden?)
syntax error at -e line 1, near "/Work/voorwaarden"
Execution of -e aborted due to compilation errors.



The string in all the index.shtml files that needs to be changed is file:///C|/Work/voorwaarden.php
This string needs to be changed to /voorwaarden.php

You can see what the mistake is all about ;-)

allan
02-05-2002, 11:02 AM
Originally posted by Domenico

The string in all the index.shtml files that needs to be changed is file:///C|/Work/voorwaarden.php
This string needs to be changed to /voorwaarden.php


Dude, you forgot to escape :).

Try this:



find /home -name *.shtml -exec perl -pi.bak -e
"s/file:\/\/\/C\|\/Work\/voorwaarden.php/voorwaarden.php/g"{} \;



(all on one line)

ScottD
02-05-2002, 11:02 AM
Yucky! Replacing /'s is always a slap in the ole honker...

I believe what you will want here for your s/ string is this:

"s&file:///C\|/Work/voorwaarden.php&/voorwaarden.php&g"

The reason for this is the conflicting /'s. Perl is nice enough to let us use pretty much any delimiter we want, so the & after the s becomes our delmiter simply because it was first.

Hope this helps!

Scott

<edit>
Or you can escape the /'s as uuallan says :D
And another edit: Fixed to escape the | per uuallens message below. Didn't feel good about keeping something potentially unsafe posted!
</edit>

allan
02-05-2002, 11:05 AM
Originally posted by DizixCom


"s&file:///C|/Work/voorwaarden.php&/voorwaarden.php&g"



Sure, do it the pansy way :D. Doublecheck this before you do it, because I think that pipe (|) will still throw you off.

Domenico
02-05-2002, 11:23 AM
:confused:

What am I doing wrong here?
I keep getting the same errors!

root@host [/home]# find /home -name *.shtml -exec perl -pi.bak -e "s/file:\/\/\/C\|\/Work\/voorwaarden.php/voorwaarden.php/g"{} \;
Not enough arguments for index at -e line 1, near "index."
Execution of -e aborted due to compilation errors.

ScottD
02-05-2002, 11:32 AM
Fixed my previous message to escape the |.

Domenico, it looks like you don't have a space between the regex string and the {} find macro.

Insert a space between ....php/g" and {} and you should be okay so it becomes:

find /home -name *.shtml -exec perl -pi.bak -e "s/file:\/\/\/C\|\/Work\/voorwaarden.php/voorwaarden.php/g" {} \;

Also, I think you wanted a / before the voorwaarden.php, so in reality you want:

find /home -name *.shtml -exec perl -pi.bak -e "s/file:\/\/\/C\|\/Work\/voorwaarden.php/\/voorwaarden.php/g" {} \;

Scott

<edit>
just realized the / missing from voorwaarden.php
</edit>

Domenico
02-05-2002, 11:39 AM
Thanks for helping me out guys!!!
This last line worked 100%

I couldn't have done it without you.
Well, that's a lie offcourse ;-) It would have taken me some more time. I completely forgot about the escaping part.

Thank you very much!
Domenico

allan
02-05-2002, 11:49 AM
Basically, you want to escape anything that would normally f up a perl program (\, |, &, and so on), so in the latest case you would want to do this (again, all on one line):



find /home -name *.shtml -exec perl -pi.bak -e
"s/\/voorwaarden.php/http:\/\/domain.com\/voorwaarden.php/g" {} \;



This will replace the line:

/voorwaarden.php

with:

http://domain.com/voorwaarden.php

allan
02-05-2002, 11:50 AM
ahh...oops, I think I just hallucinated a post :D.

Domenico
02-05-2002, 11:58 AM
Hehehehe,

That was not an hallucination, I asked about escaping the http part but lazy me asked without trying it first myself.
I succeeded so I deleted your hallucination.

Thanks anyway uuallan. It's really appreciated :)

allan
02-05-2002, 12:02 PM
Originally posted by Domenico

Thanks anyway uuallan. It's really appreciated :)

not a problem :)

Scotty_B
04-08-2003, 11:16 AM
Originally posted by allan


find /home -name *.shtml -exec perl -pi.bak -e
"s/\/voorwaarden.php/http:\/\/domain.com\/voorwaarden.php/g" {} \;



Old thread I know, but this is exactly what I need, but when I run it I just get

[QUOTE]
find: paths must precede expression
Usage: find [path...] [expression]


Any ideas?

Cheers

Scotty_B
04-09-2003, 02:22 PM
Still struggling with this, I know bumping isnt allowed but... Pretend I'm not bumping

;D

Slidey
04-09-2003, 02:26 PM
find . -name index.shtml -exec perl -pi.bak -e 's$file:\/\/\/C\|\/Work\/voorwaarden.php$voorwaarden.php$g' {} \;

that *should* work..

Scotty_B
04-09-2003, 08:19 PM
Didnt seem to work on an index.shtlm file and when i replaced index.shtml with *.htm it spewed out the same error

find: paths must precede expression
Usage: find [path...] [expression]

:(

Any other sugestions?