ディレクトリ内のすべてのファイルの内容を 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 ディレクトリに移動されました。