Solved

Linux Command Line Search & Replace Script

Posted on 2012-03-15
8
465 Views
Last Modified: 2012-03-23
I need some help writing a bash script (or something else, if suggested) that will scour recursively through all the php files in a folder and subfolders, and do a search & replace.

The text to match is quite long, so I'm guessing a script file is more appropriate than just a command line entry.

Any ideas?
0
Comment
Question by:RKFcomputers
  • 2
  • 2
  • 2
  • +2
8 Comments
 
LVL 8

Expert Comment

by:eager
ID: 37725868
Take a look at find and sed.  You can create a sed script to do the replacement and drive is using find to select the correct files.
0
 

Author Comment

by:RKFcomputers
ID: 37725962
@eager, Thanks - I know enough to know that find & sed are the likely tools to use, but not enough about how to employ them properly in this case.

(Honestly, we're an SEO company trying to help a friend. I know just enough Linux to be dangerous, as they say.)

Hence my request for help here in crafting the right approach.
0
 
LVL 16

Expert Comment

by:medvedd
ID: 37726182
find . -name "*.php" -print | xargs sed -i 's/foo/bar/g'
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:RKFcomputers
ID: 37726571
@medvedd, Thank you!

That's a great start ... but what's the best approach when "foo" is actually about 2,000+ characters?

I know how I'd handle it in PHP by putting the strings into variables ... but I'm not up enough on bash scripting to make sure I don't bugger it up.
0
 
LVL 8

Accepted Solution

by:
eager earned 500 total points
ID: 37727010
You can use a sed script.  You don't need to use xargs.  

find . -name \*.php -exec sed -f script.sed {} \;

Where script.sed contains
s/whatever/whichever/

You can use whatever delimiter you wish in place of '/' as long as it doesn't appear in your source.  You can also split your substitution into multiple patterns if that makes things easier.  Each command in the sed script is executed in order for each input line.  

Sed can be touchy at times.  Make a copy of a couple of the files and move them to a sandbox directory for testing.
0
 
LVL 77

Expert Comment

by:arnold
ID: 37727024
perl -ibak -p -e 's/patterntomatch/replacementtext/;' list_of_files
Matched files will be backed up with a .bak suffix.

Are there any other delineations I.e. the item being replaced is enclosed in comment markers //
foo nor pattern have to be the entire text being replaced, but has to be unique enough to match I.e.
Startingstring.*continuationrequiredstring.*anotherrequiredparameter
The problem is if the dt to match spans multiple lines rather being a auto wrapped single line.
In the multiline, additional options have to be used with sed or perl to look for foo to match across line.

In foo and pattern can be used as a variable
foo="pattern"
Etc.

Perl does the find and replace in a single line command.  It can be converted into a perl script with the while loop going line by line matching on the first occurrence of a defined pattern, then trying to compare the reminder to match the entire pattern.
Etc.
0
 
LVL 16

Expert Comment

by:medvedd
ID: 37728860
As @eager mentioned, you can make sed script and put long patterns there.
Be aware that usually GNU sed has a limitation of 4000 bytes for pattern length.
0
 
LVL 25

Expert Comment

by:madunix
ID: 37732164
I use the following script to replace string in directories/subdirectories/file-names/content

#!/bin/bash
ROOT_DIR="/target/directory"  # your target dir
FILTER_FILE="/directory/filter.sed"  # the sed script for renaming

# custom rename function that uses $FILTER_FILE (via sed)
function rename_using_filter {
    CURRENT_NAME="$1"
    NEW_NAME="$(echo $1 | sed -f $FILTER_FILE)"  # derive new name
    if [ "$CURRENT_NAME" != "$NEW_NAME" ]; then  # rename if diff
        mv "$CURRENT_NAME" "$NEW_NAME"
    fi
}

# for each directory, starting from deepest first
while IFS= read -r -d $'\0' DIR_NAME; do
    cd "$DIR_NAME"           # go to target dir

    # for each file/dir at this level
    while IFS= read -r -d $'\0' FILE_NAME; do
        if [ -f "$FILE_NAME" ]; then                # if it's a file
            sed -i -f "$FILTER_FILE" "$FILE_NAME"   # replace content
        fi
        rename_using_filter "$FILE_NAME"  # rename it
    done < <(find . -maxdepth 1 -print0)

    cd - > /dev/null         # back to original dir. Suppress stdout
done < <(find $ROOT_DIR -depth -type d -print0) # get only dirs




In the filter.sed put your strings
# cat filter.sed
s/old1/new1/g;
s/old2/new2/g;
s/old3/new3/g;

s/oldn-1/newn-1/g;
s/oldn/newn/g;
0

Featured Post

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Need BIOS update Linux for MSI X99A motherboard. 4 42
expectj telnet failing 5 37
AWS ELB 5 79
Perl: How to add backslashes to every period in a string 1 22
It’s 2016. Password authentication should be dead — or at least close to dying. But, unfortunately, it has not traversed Quagga stage yet. Using password authentication is like laundering hotel guest linens with a washboard — it’s Passé.
Our Group Policy work started with Small Business Server in 2000. Microsoft gave us an excellent OU and GPO model in subsequent SBS editions that utilized WMI filters, OU linking, and VBS scripts. These are some of experiences plus our spending a lo…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

803 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