単一ディレクトリのパスを使用し、そのディレクトリ内のすべてのファイルの検索文字列を置き換える次のスクリプトを作成しました。外部入力ファイルにリストされている複数のディレクトリの文字列を検索して置き換えることができるように、このスクリプトを強化したいと思います。
外部入力ファイルの内容:
/var/start/system1/dir1
/var/start/system2/dir2
/var/start/system3/dir3
/var/start/system4/dir4
1つのディレクトリを持つスクリプト:
filepath="/var/start/system/dir1"
searchstring="test"
replacestring="test01"
i=0;
for file in $(grep -l -R $searchstring $filepath)
do
cp $file $file.bak
sed -e "s/$searchstring/$replacestring/ig" $file > tempfile.tmp
mv tempfile.tmp $file
let i++;
echo "Modified: " $file
done
ベストアンサー1
sed -i
まず、GNUsed
またはsed -i ''
FreeBSD(内部交換)と組み合わせて使用すると、tmpfileダンスを回避できます。
grep -R
コマンドラインで複数のパスを使用できるため、パスにスペースが含まれていないと確信している場合$(grep -l -Re "$searchstring" "$filepath")
に置き換えることができます$(grep -l -R "$searchstring" $(cat path_list))
。
パスにスペース、タブ、またはワイルドカード文字が含まれている場合、これは失敗しますが、元のパスも同じです。
より強力なアプローチは、find
sedを使用し、それをすべてのファイルに適用して、一致しないファイルを変更しないと信じています(ここではbash
シェルを想定しています)。
# Read newline-separated path list into array from file 'path_list'
IFS=$'\n' read -d '' -r -a paths path_list
# Run sed on everything
find "${paths[@]}" \
-exec sed -i -r -e "s/$searchstring/$replacestring/ig" '{}' ';'
ただし、これは変更中のファイルに関するフィードバックを提供しません。
より長いバージョンはフィードバックを提供します。
# Read newline-separated path list into array from file 'path_list'
IFS=$'\n' read -d '' -r -a paths path_list
grep -l -R "$searchstring" "${paths[@]}" | while IFS= read -r file; do
sed -r -i -e "s/$searchstring/$replacestring/ig" "$file"
echo "Modified: $file"
done