250

次のコマンドは、2 つのファイルの内容を正しく変更しています。

sed -i 's/abc/xyz/g' xaa1 xab1 

しかし、私がする必要があるのは、そのようないくつかのファイルを動的に変更することであり、ファイル名がわかりません。現在のディレクトリからすべてのファイルを読み取り、ファイルの内容を変更xa*するコマンドを書きたいと思います。sed

4

9 に答える 9

214

一致するファイル名ごとにプロセスを開始しますが、このタイプのユースケースを対象とした find の -exec 引数について誰も言及していないことに驚いています。

find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} \;

または、より少ないプロセスを呼び出す xargs を使用することもできます。

find . -type f -name 'xa*' | xargs sed -i 's/asd/dsg/g'

または、findの代わりに+ exec バリアント;を使用して、find がサブプロセス呼び出しごとに複数のファイルを提供できるようにします。

find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} +
于 2015-06-08T19:46:05.800 に答える
161

さらに良いことに:

for i in xa*; do
    sed -i 's/asd/dfg/g' $i
done

ファイルがいくつあるかは誰にもわからず、コマンドラインの制限を簡単に破ることができるからです。

ファイルが多すぎると、次のようになります。

# grep -c aaa *
-bash: /bin/grep: Argument list too long
# for i in *; do grep -c aaa $i; done
0
... (output skipped)
#
于 2012-05-04T09:32:40.490 に答える
87

grep と sed を一緒に使用できます。これにより、サブディレクトリを再帰的に検索できます。

Linux: grep -r -l <old> * | xargs sed -i 's/<old>/<new>/g'
OS X: grep -r -l <old> * | xargs sed -i '' 's/<old>/<new>/g'

For grep:
    -r recursively searches subdirectories 
    -l prints file names that contain matches
For sed:
    -i extension (Note: An argument needs to be provided on OS X)
于 2014-03-20T13:41:21.107 に答える
36

これらのコマンドはsed、MacOSXに付属しているデフォルトでは機能しません。

差出人man 1 sed

-i extension
             Edit files in-place, saving backups with the specified
             extension.  If a zero-length extension is given, no backup 
             will be saved.  It is not recommended to give a zero-length
             extension when in-place editing files, as you risk corruption
             or partial content in situations where disk space is exhausted, etc.

試してみました

sed -i '.bak' 's/old/new/g' logfile*

for i in logfile*; do sed -i '.bak' 's/old/new/g' $i; done

どちらも正常に動作します。

于 2012-05-26T05:58:44.793 に答える
22

@PaulRはこれをコメントとして投稿しましたが、人々はそれを回答と見なす必要があります (この回答は私のニーズに最適です)。

sed -i 's/abc/xyz/g' xa*

これは、おそらく数十のオーダーの適度な量のファイルに対して機能しますが、おそらく数百万のオーダーでは機能しません

于 2015-01-23T23:23:57.727 に答える
13

別のより用途の広い方法は、次を使用することfindです。

sed -i 's/asd/dsg/g' $(find . -type f -name 'xa*')
于 2015-01-08T21:34:52.490 に答える