close

Search and Replace Recursively using sed and grep on Linux/Mac

 

I have done this so many times, still I find a new problem doing recursive search and replace each time!

Here's one just only one line command(it could be running in terminal) that puts the issues I had on the Mac/Linux doing search and replace on a match files recursively.

$ for i in $(grep -ril 'old_pattern' *); do sed "s/old_pattern/new_pattern/g" "$i" > tmp && \mv tmp "$i"; done

Below is the other ways to do search & replace patterns, which is also a  single line, it just could be run on Linux only(Mac not support such programming syntax:eg.$ sed -i ⋯」 or 「sed 's/⋯/⋯/g'」; for the later case, it just cannot work in shell script; for the first case, it cannot work both in terminal & shell script)

$ for i in $(grep -ril 'old_pattern' *); do sed -i 's/old_pattern/new_pattern/g' "$i"; done

&

$ sed -i 's/old_pattern/new_pattern/g' `grep -ril 'old_pattern' *`

 

The following script-shell code segment was shown as below, it could be work that doing search and replace on a directory recursively under the Mac/Linux.

#!/bin/sh
grep -rl $2 $1 |
 while read filename
 do
 (
  echo $filename
  sed "s/$2/$3/g;" $filename> $filename.xx
  mv $filename.xx $filename
 )
 done

Save the file as rpl.sh, chmod it 755, and execute it like:

$ ./rpl.sh folderContainingFiles/ oldPattern newPattern

 

Below is an another ways to do search & replace pattern without directory parameter under Mac/Linux.

#!/bin/bash

usage()
{
	echo "replaceStr <pattern> <new pattern>"
}

filerep()
{
	for i in $(grep -ril $1 *); do sed "s/$1/$2/g" "$i" > tmp && \mv tmp "$i"; done
}

if [ -z "$1" ]; then
	echo "It need the first argument."
	usage
elif [ -z "$2" ]; then
	echo "It need the second argument."
	usage
else
	if test "$1" && test "$2"
	then
		filerep $1 $2
	fi
fi

Save the file as replacePattern.sh, chmod it 755, and execute it like:

$ replacePattern.sh <pattern> <newPattern>

&

#!/bin/sh
# To replace pattern by new pattern for match files.

usage()
{
    echo "replacefile.sh text newtext"
}

filerep()
{
#    if grep "$1" "$filename" > /dev/null 2>&1
#    then
        echo "convert \"$2\" into \"$3\" in $filename"
        filetmp="$filename.tmp"
        echo "sed \"s/$2/$3/g\" $1 > $filetmp"
        sed "s/$2/$3/g;" $1 > $filetmp
        echo "\mv -f $filetmp $filename"
        \mv -f $filetmp $filename
#	else
#        echo "do nothing for $1 in $filename"
#    fi
}

if [ -z "$1" ]; then
    echo "Need first argument."
    usage
elif [ -z "$2" ]; then
    echo "Need second argument."
    usage
else
    if test "$1" && test "$2"
    then
        dir=`grep -ril "$1" *`
        echo "match files : $dir"
        for filename in $dir
        do
            filerep "$filename" "$1" "$2"
        done
    fi
fi

Save the file as replaceFileText.sh, chmod it 755, and execute it like:

$ replaceFileText.sh <pattern> <newPattern>

 

replaceFileText.sh」is modified from replaceall.sh . 

Both replacePattern.shreplaceFileText.sh could be work on Mac/Linux.

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Bluelove1968 的頭像
    Bluelove1968

    藍色情懷

    Bluelove1968 發表在 痞客邦 留言(1) 人氣()