I have written the code for replacing content but quite confused with replacing file name, both in the same script. I want my script to run this way:
suppose I give input : ./myscript.sh abc xyz
abc is my string to be replaced
xyz is the string to replace with
If some directory or any subdirectory or file in it has name abc, that should also change to xyz.
Here is my code:
filepath="/misc/home3/testing/fol1"
for file in $(grep -lR $1 $filepath)
do
sed -i "s/$1/$2/g" $file
echo "Modified: " $file
done
Now How should I code to replace the filename as well.
I tried:
if( *$1*==$file )
then
rename $1 $2 $filepath
fi
and
find -iname $filepath -exec mv $1 $2 \;
but any of then is not working correctly. What should I do? Which approach should I take?
Any help would be appreciated. Thanks :)
#!/bin/bash
dir=$1 str=$2 rep=$3
while IFS= read -rd '' file; do
sed -i "s/$str/$rep/g" -- "$file"
base=${file##*/} dir=${file%/*}
[[ $base == *"$str"* ]] && mv "$file" "$dir/${base//$str/$rep}"
done < <(exec grep -ZFlR "$str" "$dir")
Usage:
bash script.sh dir string replacement
Note: rename
would also rename the directory part.
grep -Z
makes it produce null-delimited outputs. i.e. it produces output which is composed of filenames in which everything is separated by 0x00
.-d ''
makes read
read input delimited by 0x00
; -r
prevents
backslashes to be interpreted; and IFS=
prevents word splitting with IFS
.IFS= read -rd ''
makes read read input with delimiter of `0base=${file##*/}
removes the directory part. It's the same as base=$(basename "$file")dir=${file%/*}
removes the file part.[[ $base == *"$str"* ]]
checks if the filename has something that could be renamed. &&
makes the command that follows it execute if the previous returns zero (true) code. Think of it as a single link if
statement."$dir/${base//$str/$rep}"
forms the new filename. ${base//$str/$rep}
replaces anything in $base
that matches value of $str
and replace it with value of $rep
.