テキスト文字列を含むファイルを検索して移動するGrepコマンド


15

次のコマンドを使用して、特定のテキスト文字列を含むフォルダー内のファイルを見つけることができます。

grep -lir 'string' ~/directory/*

上記の結果に表示されるファイルを別の場所に移動するにはどうすればよいですか?


ここにあります。 grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name
アラン・ドン

回答:


10

いつものように、注意してください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人のユーザーとして実行する場合は、競合状態とセキュリティ上の問題に注意してください。


これは私にエラー発見を与えます: `grep 'はシグナル13で終了しました。
レーナパレフ

@ReenaParekh、それはSIGPIPEになります。これはxargs、arg-fileの最後まで読み取る前に終了した場合にのみ発生します。xargs自体が強制終了されるか、何らかの理由で失敗しない限り、発生しないはずです。その場合も同様にエラーが表示されます。
ステファンシャゼラス

15

の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で)です。


3
GNU grepのはxargsのに-0フラグと一緒に使用ゼロバイト文字、によって別のファイル名に-Zフラグをサポートし、特殊文字はあなたが言及発行周りを取得することができます
iruvar

@ChandraRavooriありがとう、答えを更新しました。
ペテルフ

7

ファイル名に特殊文字(空白または\[*?)が含まれていない場合は、コマンド置換を使用します。

mv `grep -lir 'string' ~/directory/*` destination/

バックティックは非推奨です。代わりに、よりポータブルで読みやすく、スタック可能な$(...)を使用してください。
ユーザー不明

1

POSIXで指定された機能のみを使用し、ファイル名について想定していません

find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;

ノート:

あなたは「パターン」ではなく「文字列」と言ったので、-F(固定文字列検索)オプションはgrep適切なようです。

宛先ディレクトリが検索ディレクトリ内のどこかにある場合、不快な競合状態が発生している可能性があります。

POSIX仕様 grep

POSIX仕様 find


これはMacos / BSDでの最適なソリューションかもしれません。
アリ

0

GNU parallelの使用:

grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'

ht / @ lin-dongのxargsでの元の回答。


1年以上前のコメントで@lindongの回答を信用していただければ幸いでした。
ロアイマ

0

-宛先ディレクトリが「外部」であり、すべてのXLSファイルを移動する必要があると仮定すると、以下のコマンドを試すことができます

sudo mv find /var/log/ -type f -name "*.xls"/ external /

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.