web-dev-qa-db-ja.com

ファイル内の単語をGrepしてからファイルをコピーする

ファイルのコレクションがあります(* .Zip、*。txt、*。tar.gz、*。doc、... etc)。これらのファイルはパス内にあります。すべてのファイル(* .txt)を検索し、特定の単語を含むテキストファイル(たとえば、LINUX/UNIX)のみをコピーしたい。

私は以下を実行しました:

find . -name "*.txt" | grep 'LINUX/UNIX'

このコマンドはすべてのテキストファイルを見つけることができ、「grep」は「LINUX/UNIX」を含むテキストファイルのみをリストすることにより、結果のテキストファイルをフィルタリングしました。

これらの最終的なファイル(「LINUX/UNIX」を含むテキストファイル)を特定の選択したパスにコピーするにはどうすればよいですか?

xargsを適用しようとしました

find . -name "*.txt" | grep 'LINUX/UNIX' | xargs cp <to a path>

しかし、それはうまくいきませんでした

9
user88036

試してください:

grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0r cp -t /path/to/dest

このコマンドはNUL区切りを使用するため、空白、タブ、または改行を含む難しい名前のファイルを含むすべてのファイル名で安全です。

上記にはGNU cpが必要です。MacOS/ FreeBSDの場合は、次を試してください。

grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0 sh -c 'cp "$@" /path/to/dest' sh

使い方:

  1. grepオプションと引数

    • -rは、ディレクトリ構造全体を再帰的に検索するようにgrepに指示します。 (FreeBSDでは、-rはシンボリックリンクをたどってディレクトリに移動します。これは、OS/XまたはGNU grepの最近のバージョンのいずれにも当てはまりません。)

    • --include '*.txt'は、グロブ*.txt.foo.txt.txtなどの非表示のものも含む)に一致する名前のファイルのみを返すようにgrepに指示します。

    • -lは、一致自体ではなく、一致するファイルの名前のみを返すようにgrepに指示します。

    • --nullは、NUL文字を使用してファイル名を区切るようにgrepに指示します。 (--nullGNU/LinuxMacOS および FreeBSDgrepによってサポートされていますが、notOpenBSD 。)

    • LINUX/UNIXは、内容に正規表現が含まれるファイルのみを検索するようにgrepに指示しますLINUX/UNIX

    • .現在のディレクトリを検索します。 GNU grepの最近のバージョンでは省略できますが、保護するにはcp--オプションターミネータを渡す必要があります-で始まるファイル名に対して。

  2. xargsオプションと引数

    • -0は、xargsにNUL区切りの入力を期待するように指示します。

    • -rは、少なくとも1つのファイルが見つからない限り、コマンドを実行しないようにxargsに指示します。 (このオプションはBSDとOSXのどちらにも必要なく、OSXのxargsと互換性がありません。)

    • cp -t /path/to/destは、ディレクトリをターゲットディレクトリにコピーします。 (-tにはGNU cpが必要です。)

21
John1024

より移植性の高い(POSIX機能のみ):

find . -type f -name '*.txt' -exec grep -q LINUX/UNIX {} \; -exec cp {} /path/to/dest \;
13
Wildcard

次のsh/Bashの1つのライナーは別の方法ですが、現在のディレクトリでのみ機能し、再帰しません。

for f in ./*.txt; do if grep -l 'LINUX/UNIX' "$f"; then cp "$f" /path/to/dest/; fi; done

-l grepのオプションは、コピーされているファイルのリストを出力しますが、-q画面に何も表示したくない場合。

3
Arronical

元の文字列が機能しなかった理由がわかりません。次のコマンドは私のために働きます。

検索/ -name(ファイル名*)| grep '(filename.extention)' | xargs cp -t ./

私の場合、filename *は同じ名前のファイルのコレクションで、異なるファイルタイプ(txt、Zipなど)です。 grepを実行して、filename.txtだけを見つけ、それを宛先ディレクトリー(現在は./)にコピーします。

0
SamL