シェルのディレクトリで grep と mv を一緒に使用するにはどうすればいいですか?

シェルのディレクトリで grep と mv を一緒に使用するにはどうすればいいですか?

ディレクトリ内のすべてのファイルの内容を grep で「TEST」として検索し、それらのファイルを別のディレクトリ (ホーム ディレクトリなど) に移動するにはどうすればよいでしょうか。

答え1

組み合わせることができますグレップそして探すこのタスクの場合:

find SOURCE -maxdepth 1 -type f -exec grep -q TEST {} \; -exec mv -i {} DEST \;

使い方

  • find SOURCE -maxdepth 1 -type f-type fディレクトリ内のすべてのファイル( )を検索しますソース

    サブディレクトリ内のファイルも含める場合は、 を削除するだけです-maxdepth 1

  • -exec grep -q TEST {} \;ファイルを一つずつgrepして文字列を検索するテスト. ここに、{}現在処理中のファイルがあります。

    この-qスイッチはgrepを「静かに」します。つまり、何も出力しません。この-exec文は、次の場合に真となります。グレップ成功しました。つまり、文字列が見つかりました。

  • -exec mv -i {} DEST \;文字列を含むファイルを移動するテストディレクトリに目的地

    スイッチ-i動画「対話型」、つまり、他のファイルを上書きする前にプロンプ​​トを表示します。

答え2

もう 1 つの代替案 (ただし、これには GNU 固有の拡張機能がいくつか必要です。質問に「Unix」のタグが付けられているため、適していない可能性があります)。

grep -lZd skip TEST SOURCE/* | xargs -0I{} mv -i {} DEST
  • grep -l

    通常の出力の代わりに一致するファイル名を出力します。

  • grep -Z

    ヌルバイトで区切られた出力を生成します。これは、パイプ経由で奇妙なファイル名を処理する場合に安全です。

  • grep -d skip

    skip入力引数の中で検出されたディレクトリに対するアクションを定義します。

    これは実際には必要ありません。ディレクトリに遭遇したときに通知を回避するだけですgrep: SOURCE/DIR: Is a directory。ディレクトリ内のファイルを再帰的に読み取りたい場合は、アクションを使用するrecurseか、同等のスイッチをさらに短くします-r(以下の点も参照)。

  • SOURCE/*

    SOURCEシェルを使用してディレクトリ内のすべてのファイルに一致しますグロビング隠しファイルはデフォルトでは一致しません。これは、コマンドを発行するshopt -s dotglob前に Bash で設定することで変更できます。grep

    SOURCE/.*入力引数に単に追加したいという誘惑に駆られるかもしれませんが、これを と で使用すると予期しない結果になる可能性があります (とも-r一致するため)。...

    再帰的な一致が必要な場合は、-r SOURCEディレクトリ構造内の隠しファイルを含むファイルグロブなしで入力引数として使用します。

  • xargs -0

    入力を null で区切られたものとして解釈します。

  • xargs -I{}

    {}入力引数のプレースホルダーとして定義します。

  • mv -i

    間違いを避けるために、デニスの提案に従って移動をインタラクティブにします。

このパターン (または一般的なコマンド) をテストするには、echo実際のコマンドの前に を挿入して、どのコマンドが実行されるかを確認する (つまりmvに変更する) という便利な手法がありますecho mv

答え3

$ mv TEST* /path/to/destination

私にとってはうまくいきました。あなたにもうまくいくことを願っています。私の場合は次のとおりでした:

$ mv note_[5,6]* ~/documents/notes

これにより、note_5_math.pdf と note_6_math.pdf が home/documents/notes ディレクトリに移動されました。

関連情報