パターンのディレクトリ内の文字列を再帰的にgrepし、一致するファイルを宛先ディレクトリにcpすることに興味があります。私は次のようなことができると思ったが、linuxの検索ツールでは意味がなさそうだ。
find . -type f -exec grep -ilR "MY PATTERN" | xargs cp /dest/dir
これについてより良い方法はありますか?あるいは、うまくいく方法でもしっかりしたスタートです。
man xargs
を実行し、-I
フラグを確認します。
find . -type f -exec grep -ilR "MY PATTERN" {} \; | xargs -I % cp % /dest/dir/
また、find
では、\;
フラグの後に+
または-exec
が必要です。
xargs
は、その標準入力を読み取り、実行するコマンドの最後に置きます。あなたがそれを書いたように、あなたは実行してしまうでしょう
cp /dest/dir sourcefile1 sourcefile2 sourcefile3
これはあなたが望むものとは逆です。
次のように、-I
オプションを使用して、xargs
のプレースホルダーを指定できます:xargs -I '{}' cp '{}' /dest/dir
。
また、find
は再帰を処理するため、grep
は-R
を必要としません。
最終的解決:
find . -type f -exec grep -il "MY PATTERN" '{}' + | xargs -I '{}' cp '{}' /dest/dir
あなたが見つける必要はないと思います。再帰的なgrep:
grep -rl "MY PATTERN" .
上記の例では、grep
の可能性を考慮していません-l
重複した結果(同じ名前で場所が異なるファイル)を生成しているため、find
のexec
のフックが宛先ディレクトリのファイルを上書きしています。
これを解決する試み:
$ tree foo
foo
├── bar
│ ├── baz
│ │ └── file
│ └── file
├── destdir
└── file
3 directories, 3 files
$ while read a; do mv $a foo/destdir/$(basename $a).$RANDOM; done < <(grep -rl content foo)
$ tree foo
foo
├── bar
│ └── baz
└── destdir
├── file.10171
├── file.10842
└── file.25404
3 directories, 3 files