yos*_*rry 7 command-line terminal find
我已经学会了单独使用 find 命令来查找文件和目录,但是当涉及到对文件/文件夹执行某些操作时,我感到很困惑。
给出以下命令:
find . -type f -iname "*.cr2"
Run Code Online (Sandbox Code Playgroud)
如果我想将上面找到的那些文件复制到一个新目录中,我自然会认为使用 copy( cp) 和 pipe |。
find . -type f -iname "*.cr2" | cp \destination_directory
Run Code Online (Sandbox Code Playgroud)
对我来说,这将使我所有的照片跨越整个驱动器,并嵌套在子文件夹的级别中,放入一个准备开始组织的文件夹中。
但是人们一直告诉我使用该-exec参数,所以我的问题是您如何知道何时使用管道|以及何时使用-exec如下命令?
find . -name "*.pdf" -type f -exec cp {} ./pdfsfolder \;
Run Code Online (Sandbox Code Playgroud)
编辑
建议的解决方案(如下)仅复制文件名唯一的文件。它说cp不会复制file.txt并替换为file.txt。在你复制很多文件的情况下,不知道是否会有同名的文件,如果文件名存在,你如何复制并重命名它?
建议的解决方案
find . -type f -iname "*.txt" -print0 | xargs -0 cp -t /home/josh/Documents/copy/
Run Code Online (Sandbox Code Playgroud)
/home/josh/documents/copy 是我要将内容移动到的目录。
Ant*_*hon 12
您的假设存在错误,但首先要了解一些背景:
您应该辨别 的两种用途-exec:
\;该{} 会由单一发现商品被替换+该{}会由许多项目来替换(多达命令行可以容纳)。因此,您的-exec使用示例调用的cp命令与find.
usingfind ... -exec cmd {} ... +在效率上与将 find 的输出管道传输到处理多个输入名称的命令中的效率相似。
您还应该考虑到它可以-exec很好地处理带有空格的文件名/路径,但是当您将输出从 find 管道传输到另一个可能会导致问题的程序时。因此,一些需要来自 stdin 的文件名列表的程序可以选择将这些文件名 NUL 分隔(通常-0或--null)。并且find可以选择通过指定以下方式将它们提供给下一个程序:-print0
现在来看看你的例子:
find . -type f -iname "*.cr2" | cp destination_directory
Run Code Online (Sandbox Code Playgroud)
不复制找到的文件,因为 cp 不从标准输入读取。你将不得不使用:
find . -type f -iname "*.cr2" | xargs cp -t destination_directory
Run Code Online (Sandbox Code Playgroud)
或处理带空格的路径:
find . -type f -iname "*.cr2" -print0 | xargs -0 cp -t destination_directory
Run Code Online (Sandbox Code Playgroud)
以大致相同的效率,您可以执行以下操作:
find . -type f -iname "*.cr2" -exec cp -t destination_directory {} +
Run Code Online (Sandbox Code Playgroud)
(正如 G-Man 指出的那样{},必须在最后,在 之前+)以上所有内容都没有为此在目标目录下构建层次结构,并且即使源目录是扁平的,出于长期习惯,我发现自己使用cpio反而:
find . -type f -iname "*.cr2" -print0 | cpio -pdmv0 destination_directory
Run Code Online (Sandbox Code Playgroud)
它很好地列出了它在此过程中所做的事情。
相关部分来自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.
Run Code Online (Sandbox Code Playgroud)