
ファイルコレクション(*.zip、*.txt、*.tar.gz、*.doc、...など)があります。これらのファイルはパスにあります。すべてのファイル(* .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>
しかし成功はありません。
答え1
努力する:
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
仕組み:
grep
オプションとパラメータ-r
ディレクトリ構造から再帰的に検索するように grep に指示します。 (FreeBSDでは-r
ディレクトリへのシンボリックリンクが続きます。OS / Xや最新バージョンのGNUではありませんgrep
。)--include '*.txt'
名前がglobと一致するファイル(または*.txt
同じ隠しファイルを含む)のみを返すようにgrepに指示します。.foo.txt
.txt
-l
一致するファイル自体ではなく、一致するファイルの名前のみを返すようにgrepに指示します。--null
ファイル名を区別するために NUL 文字を使用するよう grep に指示します。 (--null
応募者:grep
GNU/Linux、アップルシステムそしてFreeBSDしかし、いいえ オープンBSD.)LINUX/UNIX
内容に正規表現を含むファイルのみを検索するようにgrepに指示するLINUX/UNIX
.
現在のディレクトリから検索します。最新バージョンのGNUではこれを省略できますが、で終わらないようにするには、オプションの終端を渡すgrep
必要があります。--
cp
-
xargs
オプションとパラメータ-0
NULで区切られた入力を期待するようにxargsに指示します。-r
1 つ以上のファイルが見つからない場合は、コマンドを実行しないように xargs に指示します。 (このオプションはBSDまたはOSXでは必要ではなく、OSXと互換性がありませんxargs
。)cp -t /path/to/dest
ディレクトリを宛先ディレクトリにコピーします。 (-t
GNUが必要ですcp
。)
答え2
移植性の向上(POSIX機能のみ):
find . -type f -name '*.txt' -exec grep -q LINUX/UNIX {} \; -exec cp {} /path/to/dest \;
答え3
次のsh / Bash onelinerは別のアプローチですが、現在のディレクトリでのみ機能し、繰り返されません。
for f in ./*.txt; do if grep -l 'LINUX/UNIX' "$f"; then cp "$f" /path/to/dest/; fi; done
grepオプションは-l
コピーされるファイルのリストを印刷しますが、-q
画面に何も表示したくない場合は、このオプションを使用できます。
答え4
なぜ生の文字列が機能しないのかわかりません。次のコマンドが私にとって効果的でした。
/ -name(ファイル名*)| grep '(filename.extension)' | xargs cp -t ./
私の場合、filename *は同じ名前ですが、ファイル形式(txt、zipなど)が異なるファイルのコレクションです。 grepを介してfilename.txtのみを見つけて、ターゲットディレクトリ(現在の./)にコピーします。