Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2004
    Posts
    2
    Rep Power
    0

    Unix find and replace text within all files within a directory


    I am trying to do a search on an entire directory, finding all the instances of the text "applicationX" and replacing all instances with the text "applicationY".

    I created the following to find all instances and print the files that contain the search text. But now I don't know how to replace the text.

    find . -type f -exec grep "applicationX" {} \; -print

    Please help..thanks
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,625
    Rep Power
    4247
    Here's something I cooked up. The grep -il statement finds all instances of Hello in files ending in txt (i = ignore case, , l = only list the filename). The file names are passed to sed, which runs a regular expression to change all instances of Hello to Goodbye. Since sed doesn't overwrite a file, I redirected the output to a temp file and then renamed it back to the original file name.
    Code:
    #!/bin/sh
                              
    for file in $(grep -il "Hello" *.txt)
    do
    sed -e "s/Hello/Goodbye/ig" $file > /tmp/tempfile.tmp
    mv /tmp/tempfile.tmp $file
    done
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  4. #3
  5. Introspective
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Nov 2001
    Location
    London, UK
    Posts
    3,317
    Rep Power
    110
    or you could just aswell use PERLs inplace replacement as in the following one-liner:

    find /path/to/start/from/ -type f | xargs perl -pi -e 's/applicationX/applicationY/g'

    christo
    This is me: http://chris.uk.com
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2004
    Posts
    2
    Rep Power
    0
    The second solution worked perfectly.

    The first one actually will delete all the contents of the file if there is more than one instance of the search string in the file. I actually had played around with another variation that did the same thing:

    find . -type f -name '*.txt' -print | while read i
    do
    sed 's|applicationx|applicationy|g' $i > $i.tmp && mv $i.tmp $i
    done

    Maybe a little fiddling around would get a solution.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2002
    Posts
    60
    Rep Power
    13
    To replace all instances of a string in a directory (subdirectories included) do:
    Code:
    perl -e "s/FIND/REPLACE/g;" -pi.save $(find path/to/DIRECTORY -type f)
    The above will make a backup temp file of your original
    If you do not want a temp file with the .save extension then do:

    Code:
    perl -e "s/FIND/REPLACE/g;" -pi $(find path/to/DIRECTORY -type f)
    --------------------
    Example:
    You want to replace all instances of the word "design" with "dezine" in the directory /public_html/company/info

    you can execute the command from document root as
    Code:
    perl -e "s/design/dezine/g;" -pi.save $(find public_html/company/info -type f)
    or you can execute the command from public_html/company/ (a directory above) as:
    Code:
    perl -e "s/design/dezine/g;" -pi.save $(find info -type f)
    ------------------------------

    The above commands will search all files (.gif, .jpg, .htm, .html, .txt) so you might see some error messages "Can't open *.gif", etc)

    Simplified

    To search just files of type, .htm without a backup file in the current directory only (no subdirectories) you could use:

    Code:
    perl -pi -e 's/design/dezine/g' *.htm
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2008
    Posts
    1
    Rep Power
    0
    Originally Posted by Scorpions4ever
    Here's something I cooked up. The grep -il statement finds all instances of Hello in files ending in txt (i = ignore case, , l = only list the filename). The file names are passed to sed, which runs a regular expression to change all instances of Hello to Goodbye. Since sed doesn't overwrite a file, I redirected the output to a temp file and then renamed it back to the original file name.
    Code:
    #!/bin/sh
                              
    for file in $(grep -il "Hello" *.txt)
    do
    sed -e "s/Hello/Goodbye/ig" $file > /tmp/tempfile.tmp
    mv /tmp/tempfile.tmp $file
    done
    very cool script. Thanks for posting. I modified it a bit, and this seems to work pretty well:
    Code:
    # *****************************************************************************************
    # find_and_replace_in_files.sh
    # This script does a recursive, case sensitive directory search and replace of files
    # To make a case insensitive search replace, use the -i switch in the grep call
    # uses a startdirectory parameter so that you can run it outside of specified directory - else this script will modify itself!
    # *****************************************************************************************
    
    !/bin/bash
    # **************** Change Variables Here ************
    startdirectory="/home/gare/tmp/tmp2"
    searchterm="search"
    replaceterm="replaceTerm"
    # **********************************************************
    
    echo "******************************************"
    echo "* Search and Replace in Files Version .1 *"
    echo "******************************************"
    
            for file in $(grep -l -R $searchterm $startdirectory)
              do
               sed -e "s/$searchterm/$replaceterm/ig" $file > /tmp/tempfile.tmp
               mv /tmp/tempfile.tmp $file
               echo "Modified: " $file
            done
    
    echo " *** Yay! All Done! *** "
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    3
    Rep Power
    0

    Script Modified for User Input


    I modified the Scorpions4ever script so it allows for user input so that you dont have to alter the script to do a search.

    edit: I changed the script to work with Zenity in Gnome.

    Code:
    #!/bin/sh
    
    echo enter file name with extension
    read NAME
    echo enter word to replace
    read FIND
    echo enter word that replaces
    read REPLACE                         
    for file in $(grep -il "$FIND" $NAME)
    do
    sed -e "s/$FIND/$REPLACE/ig" $file > /tmp/tempfile.tmp
    mv /tmp/tempfile.tmp $file
    done
    Only thing I can't figure out is how to run it from Nautilus Actions Configuration. I want it to be on the right click menu so that you can select multiple files and do batch replacements. I tried adding "gnome-terminal" to the beginning of the script but it doesn't work and my bash writing skills are minimal. I only know variable juggling.

    I tried adding this line to the end before "done"

    Code:
    gnome-terminal -e /home/$USER/.gnome2/nautilus-scripts/scriptname
    This actually popped up a terminal window and it seemingly went through the script operations but it didn't change the file I selected. Is there some way to name the file you select as a variable in the script?

    I want it to be so that I can select multiple files with the mouse and right click with a simple "find and replace" function for batch editing, sort of like the batch-resize option that I added through Nautilus Actions Configuration Editor.

    With Zenity, provides GUI question box:

    Code:
    #!/bin/sh
    
    szAnswer0=$(zenity --entry --text "Enter file names and paths" --entry-text $PWD);
    szAnswer1=$(zenity --entry --text "Enter word to replace:");
    szAnswer2=$(zenity --entry --text "Enter word that replaces:");                     
    for file in $(grep -il "$szAnswer1" $szAnswer0)
    do
    sed -e "s/$szAnswer1/$szAnswer2/ig" $file > /tmp/tempfile.tmp
    mv /tmp/tempfile.tmp $file
    done
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2006
    Posts
    177
    Rep Power
    234
    Code:
    find . -type f -print0 | xargs -0 sed -i 's/Application/whatever/g'
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    3
    Rep Power
    0

    Nedit


    yea, probably quicker to use NEDIT. It has a fantastic search and replace function, though a script to run a right click option on the mouse in nautilus is still interesting for search and replace.
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    3
    Rep Power
    0

    Thanks


    Originally Posted by ghostdog74
    Code:
    find . -type f -print0 | xargs -0 sed -i 's/Application/whatever/g'
    Nice one. I changed it to a bash script like so:

    Code:
    #!/bin/bash
    szAnswer1=$(zenity --entry --text "Enter word to replace:");
    szAnswer2=$(zenity --entry --text "Enter word that replaces:");   
    find . -type f -print0 | xargs -0 sed -i "s/$szAnswer1/$szAnswer2/g"
    Then I moved the script file to /bin so it could be called as a single file name in terminal. Then I called it through Nautilus-Actions conf editor which added it to right click menu. Only problem is it doesn't work on desktop. It only shows up inside a directory, which is just as well, and it replaces the term for every file in the directory without calling a specific file.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    1
    Rep Power
    0

    In that example - how to filter specific lines?


    In this example:
    find . -type f -print0 | xargs -0 sed -i 's/Application/whatever/g'

    How can I filter that it will replace only lines starting with the string "#include"

    I need to replace some string as above but only on lines starting with the "#include" string.

    Thanks in advance,

    Ofer
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2009
    Posts
    1
    Rep Power
    0
    Hi Everyone. I just joined. what a wealth of info here. I was looking for something very similar to what these scripts do. I have a YaBB forum where I need to go into hundreds of *.vars files and search for a text string and if it finds it I want to replace the whole line not just the search string. Optionally it could report back a list of *.vars files that it did not find the search string in.



    thanks
    DC
  24. #13
  25. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2010
    Posts
    1
    Rep Power
    0

    A simple Perl example


    Originally Posted by bjmazur2
    I am trying to do a search on an entire directory, finding all the instances of the text "applicationX" and replacing all instances with the text "applicationY".

    I created the following to find all instances and print the files that contain the search text. But now I don't know how to replace the text.

    find . -type f -exec grep "applicationX" {} \; -print

    Please help..thanks
    perl -pi -w -e 's/search/replace/g;' *.c

    -p loop
    -i means edit in-place
    -w write warnings
    -e means execute the following line of code.
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2010
    Posts
    1
    Rep Power
    0

    Remove ^M


    Can you please modify this script to remove ^M from multiple files at once.


    Originally Posted by gare
    very cool script. Thanks for posting. I modified it a bit, and this seems to work pretty well:
    Code:
    # *****************************************************************************************
    # find_and_replace_in_files.sh
    # This script does a recursive, case sensitive directory search and replace of files
    # To make a case insensitive search replace, use the -i switch in the grep call
    # uses a startdirectory parameter so that you can run it outside of specified directory - else this script will modify itself!
    # *****************************************************************************************
    
    !/bin/bash
    # **************** Change Variables Here ************
    startdirectory="/home/gare/tmp/tmp2"
    searchterm="search"
    replaceterm="replaceTerm"
    # **********************************************************
    
    echo "******************************************"
    echo "* Search and Replace in Files Version .1 *"
    echo "******************************************"
    
            for file in $(grep -l -R $searchterm $startdirectory)
              do
               sed -e "s/$searchterm/$replaceterm/ig" $file > /tmp/tempfile.tmp
               mv /tmp/tempfile.tmp $file
               echo "Modified: " $file
            done
    
    echo " *** Yay! All Done! *** "
  28. #15
  29. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2010
    Posts
    1
    Rep Power
    0
    To replace ^M character:

    This one for Solaris 10 box:
    for i in `find . -type f` ; do dos2unix $i $i; done

Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo