選択したディレクトリ内の複数のファイルの文字列を置き換えるシェルスクリプト

選択したディレクトリ内の複数のファイルの文字列を置き換えるシェルスクリプト

単一ディレクトリのパスを使用し、そのディレクトリ内のすべてのファイルの検索文字列を置き換える次のスクリプトを作成しました。外部入力ファイルにリストされている複数のディレクトリの文字列を検索して置き換えることができるように、このスクリプトを強化したいと思います。

外部入力ファイルの内容:

/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))

パスにスペース、タブ、またはワイルドカード文字が含まれている場合、これは失敗しますが、元のパスも同じです。

より強力なアプローチは、findsedを使用し、それをすべてのファイルに適用して、一致しないファイルを変更しないと信じています(ここでは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

おすすめ記事