回答:
いつものように、注意してくださいgrep -r
。-r
は標準オプションではなく、GNUのごく最近のバージョン以外の一部の実装grep
では、ディレクトリツリーを下るときにシンボリックリンクをたどります。これは一般に望んでいないものであり、たとえば「/ "ディレクトリツリーのどこかに。
Unixの哲学では、コマンドを使用してディレクトリのファイルを検索し、別のコマンドを使用してその内容を確認します。
GNUツールを使用して、次のことを行います。
xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
) mv -i --target-directory /dest/dir
ただし、それでも、他のユーザーが書き込み可能なディレクトリで1人のユーザーとして実行する場合は、競合状態とセキュリティ上の問題に注意してください。
xargs
、arg-fileの最後まで読み取る前に終了した場合にのみ発生します。xargs自体が強制終了されるか、何らかの理由で失敗しない限り、発生しないはずです。その場合も同様にエラーが表示されます。
の3番目の構文xargs
と組み合わせて使用しmv
ます。mv [OPTION]... -t DIRECTORY SOURCE...
grep -lir 'string' ~/directory/* | xargs mv -t DEST
特殊文字(スペース、引用符)を含むファイルには注意してください。この場合、リストをフィルタリングするsed
(ファイル名の前後に引用符を追加するs/^/'/;s/$/'/
)と役立つかもしれませんが、これらの引用符はファイル名に表示されないことを確認する必要があります。GNUにgrep
は、ファイル名をNULで終了する-Z
/ --null
オプションがあります。
3番目の構文の代わりに、プレースホルダー文字列()mv
を使用xargs
します-I
。
もう1つのオプションは、コマンド置換です。$( )
または``
、ire_and_cursesの回答に記載されているように、バックティック(bashで)です。
POSIXで指定された機能のみを使用し、ファイル名については想定していません。
find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;
ノート:
あなたは「パターン」ではなく「文字列」と言ったので、-F
(固定文字列検索)オプションはgrep
適切なようです。
宛先ディレクトリが検索ディレクトリ内のどこかにある場合、不快な競合状態が発生している可能性があります。
grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'
ht / @ lin-dongのxargsでの元の回答。
grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name