Web Hosting Talk







View Full Version : UNIX/Linux Find & Replace


Bee
06-12-2002, 01:31 AM
I'm migrating a site from one server to another. The site has several hundred CGI scripts that scatter around in different subdirectories. I need to change the shebang line in all the scripts. Instead of manually edit all the scripts, is there is UNIX/Linux command or utility that can make my life easier. If yes, can you give me specific instructions? Thanks!

Need to change from...
#!/usr/local/bin/perl

to...
#!/usr/bin/perl

INurv
06-12-2002, 01:37 AM
Can't you just make a symbolic link to the perl you have on the machine?

e.g:

# ln -s /usr/bin/perl /usr/local/bin/perl

Maybe I'm totally wrong.

chrisb
06-12-2002, 05:12 AM
You could also use "glob" with a regex.

Matt Lightner
06-12-2002, 05:17 AM
This command should do what you're looking for.

Here is my disclaimer: This might not work. It has not been tested. If it doesn't work, it might erase files. Don't run it before backing up all of the files you need. I'm not responsible for any damage this does to your system. In fact, I'm not even recommending that you use this command at all--the symlink idea is much safer and better in the long run. How's that for confidence in my work? :)

But if you do end up using it, it would probably be a good idea to run it as a non-privlidged user just to be on the safe side. Be sure to set the target directory correctly in the command.

perl -pi -e 's/^\#\!\/usr\/local\/bin\/perl/\#\!\/usr\/bin\/perl/' \
`find /path/to/files/here -type f`

chrisb
06-12-2002, 08:02 AM
Hmmm... don't know what I was thinking. Glob isn't the best way to handle this. Using File:Find is the best way as Matt did above. Also, symbolic links can be dangerous.

Be sure and change /directory/path below to the exact path of the top directory that you want your search and replace to start. Here ya go!

find /directory/path -type f | xargs perl -pi -e 's/\/local//g'

No disclaimer necessary ;)

BTW, Matt... good to see a host that knows his perl.

allan
06-12-2002, 09:40 AM
This has been discussed before:

http://www.webhostingtalk.com/showthread.php?s=&threadid=34600

Diz and I came up with a pretty good solution :).

Bee
06-12-2002, 09:37 PM
Based on the info you guys provided, I did the following but it didn't work. I need it to find/replace recursively from the /home directory down. What am I missing? Thanks for all your help.

Change from...
#!/usr/local/bin/perl

To...
#!/usr/bin/perl

find /home -name *.cgi -exec perl -pi.bak -e "s/usr\/local\/bin\/perl/usr\/bin\/perl/g" {} \;

allan
06-12-2002, 09:52 PM
Originally posted by Bee

Change from...
#!/usr/local/bin/perl

To...
#!/usr/bin/perl

find /home -name *.cgi -exec perl -pi.bak -e "s/usr\/local\/bin\/perl/usr\/bin\/perl/g" {} \;

Hmm...that looks like it should work, but lets make it even easier. If you don't have any other reference to /local in your scripts, then we don't really need to replace all that text, we just need to remove the /local, right?

Try this (I just tested it on my system and it worked):


find home -name *.cgi -exec perl -pi.bak -e "s/\/local//g" {
} \;


Run the command from the directory above the home directory (prolly the root directory).

roly
06-12-2002, 11:00 PM
Instead of find and replace try this:

As root run:
cp /usr/local/bin/perl /usr/bin/perl

ScottD
06-12-2002, 11:16 PM
Originally posted by roly
Instead of find and replace try this:

As root run:


That's messy. Workarounds are troublesome in the future, keep your system clean and fix the problem instead of hiding from it. :)

chrisb
06-13-2002, 01:13 AM
Originally posted by Bee
Based on the info you guys provided, I did the following but it didn't work. I need it to find/replace recursively from the /home directory down. What am I missing? Thanks for all your help.

find /home -name *.cgi -exec perl -pi.bak -e "s/usr\/local\/bin\/perl/usr\/bin\/perl/g" {} \;


You're welcome. Sorry you didn't get it to work though.

Whaddaya mean, "you guys".:) That wasn't what I posted. My solution was the below CODE and doesn't have all of those unnecessary characters in the regex. Did you try it? Did you try it thru telnet or in a perl file? If you tried it in a file, you would need to add

use File:Find;

### START OF CODE
find /directory/path -type f | xargs perl -pi -e 's/\/local//g';
### END OF CODE

BTW, I purposely left ".bak" out of my suggestion, because I felt confident that it would not mess up your files, and I didn't see the need for making .bak backup files and then having to remove them.

Datawire: Looks like the other thread is a bit different. It's about replacing file names as in $_. This one is about replacing text within files.