ファイルやディレクトリを見つけるために find コマンドを単独で使用する方法を学習しましたが、ファイルやフォルダを使用して何かを行うとなると混乱してしまいます。
次のコマンドを実行します。
find . -type f -iname "*.cr2"
cp
上記のファイルを新しいディレクトリにコピーしたい場合は、当然 copy( ) と pipe を使用すると思います|
。
find . -type f -iname "*.cr2" | cp \destination_directory
そして私にとっては、これにより、ドライブ全体にわたるすべての写真がサブフォルダーの階層にネストされて 1 つのフォルダーにまとめられ、整理を始める準備が整います。
しかし、パラメータを使用するように言われ続けるので、私の質問は、以下のようにいつパイプを使用し、いつコマンドを使用するかを-exec
どのように判断するかということです。|
-exec
find . -name "*.pdf" -type f -exec cp {} ./pdfsfolder \;
編集
提案された解決策 (下記) は、ファイル名が一意であるファイルのみをコピーします。cp は file.txt をコピーせず、file.txt に置き換えます。多数のファイルをコピーし、同じ名前のファイルがあるかどうかわからない場合、ファイル名が存在する場合に何かをコピーして名前を変更するにはどうすればよいでしょうか。
提案された解決策
find . -type f -iname "*.txt" -print0 | xargs -0 cp -t /home/josh/Documents/copy/
/home/josh/documents/copy は、データを移動したいディレクトリです。
答え1
あなたの仮定には誤りがありますが、まず背景を説明します。
の 2 つの用途を認識する必要があります-exec
。
- は、
\;
見つかっ{}
た単一のアイテムに置き換えられます - は、
+
多く{}
の項目 (コマンドラインに保持できる数だけ) に置き換えられます。
したがって、使用例では、 によって見つかった項目と-exec
同じ数のコマンドが呼び出されます。cp
find
を使用するfind ... -exec cmd {} ... +
と、find の出力を複数の入力名を処理するコマンドにパイプするのと効率が似ています。
-exec
また、スペースを含むファイル名/パスを適切に処理しますが、find からの出力を別のプログラムにパイプすると問題が発生する可能性があることも考慮する必要があります。したがって、stdin からファイル名のリストを期待する一部のプログラムには、それらのファイル名を NUL で区切るオプション (多くの場合、または-0
)--null
を指定できます。また、find
次のように指定することで、次のプログラムにそのように渡すオプションがあります。-print0
さて、あなたの例を見てみましょう:
find . -type f -iname "*.cr2" | cp destination_directory
cp は標準入力から読み込まないため、見つかったファイルをコピーしません。次のように使用する必要があります。
find . -type f -iname "*.cr2" | xargs cp -t destination_directory
または、スペースを含むパスを処理するには:
find . -type f -iname "*.cr2" -print0 | xargs -0 cp -t destination_directory
ほぼ同じ効率で、次の操作を実行できます。
find . -type f -iname "*.cr2" -exec cp -t destination_directory {} +
(G-Manが指摘したように、 は{}
の前の最後になければなりません+
)上記のすべてはないそのためにターゲット ディレクトリの下に階層を構築し、長年の習慣により、ソース ディレクトリがフラットであっても、cpio
代わりに以下を使用するようになりました。
find . -type f -iname "*.cr2" -print0 | cpio -pdmv0 destination_directory
途中で何を実行しているかをわかりやすくリストします。
関連部分man find
:
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command
until an argument consisting of `;' is encountered. The string
`{}' is replaced by the current file name being processed
everywhere it occurs in the arguments to the command, not just
in arguments where it is alone, as in some versions of find.
Both of these constructions might need to be escaped (with a
`\') or quoted to protect them from expansion by the shell.
See the EXAMPLES section for examples of the use of the -exec
option. The specified command is run once for each matched
file. The command is executed in the starting directory.
There are unavoidable security problems surrounding use of the
-exec action; you should use the -execdir option instead.
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end; the total number of invoca‐
tions of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of `{}'
is allowed within the command. The command is executed in the
starting directory.