フォルダー(およびそのサブフォルダー)内のすべてのファイルで正規表現の検索と置換を行う必要があります。それを行うためのLinux Shellコマンドは何ですか?
たとえば、これをすべてのファイルに対して実行し、古いファイルを新しい置換テキストで上書きします。
sed 's/old text/new text/g'
Sedのみを使用して実行する方法はありません。少なくともfindユーティリティを一緒に使用する必要があります。
find . -type f -exec sed -i.bak "s/foo/bar/g" {} \;
このコマンドは、変更されたファイルごとに.bak
ファイルを作成します。
注:
sed
コマンドの-i
引数はGNU拡張です。そのため、このコマンドをBSDのsed
で実行している場合は、出力を新しいファイルにリダイレクトし、名前を変更します。find
ユーティリティは、古いUNIXボックスの-exec
引数を実装しないため、代わりに| xargs
を使用する必要があります。覚えやすいので、find | xargs cmd
よりfind -exec
を使用する方が好きです。
この例では、現在のディレクトリ以下の.txtファイルで「foo」を「bar」にグローバルに置き換えます。
find . -type f -name "*.txt" -print0 | xargs -0 sed -i "s/foo/bar/g"
ファイル名にスペースなどのファンキーな文字が含まれていない場合、-print0
および-0
オプションは省略できます。
移植性のために、LinuxやBSDに固有のsedの機能に依存しません。代わりに、KernighanとPikeのUnixプログラミング環境に関する本のoverwrite
スクリプトを使用します。
コマンドは
find /the/folder -type f -exec overwrite '{}' sed 's/old/new/g' {} ';'
そして、overwrite
スクリプト(私はあちこちで使用しています)は
#!/bin/sh
# overwrite: copy standard input to output after EOF
# (final version)
# set -x
case $# in
0|1) echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2
esac
file=$1; shift
new=/tmp/$$.new; old=/tmp/$$.old
trap 'rm -f $new; exit 1' 1 2 15 # clean up files
if "$@" >$new # collect input
then
cp $file $old # save original file
trap 'trap "" 1 2 15; cp $old $file # ignore signals
rm -f $new $old; exit 1' 1 2 15 # during restore
cp $new $file
else
echo "overwrite: $1 failed, $file unchanged" 1>&2
exit 1
fi
rm -f $new $old
これは、コマンドが成功した場合にのみファイルを上書きするという考え方です。 find
で有用であり、使用したくない場所でも
sed 's/old/new/g' file > file # THIS CODE DOES NOT WORK
sed
が読み取ることができる前に、シェルがファイルを切り捨てるためです。
私は(ファイルをバックアップした後)提案するかもしれません:
find /the/folder -type f -exec sed -ibak 's/old/new/g' {} ';'