我正在通过终端使用Bash命令在Mac计算机上工作。
我有~200个编号为0-200的目录。每个目录包含以.fast5结尾的5,000个单独文件。我试图找出将200个目录组中的所有文件合并到一个名为Consolidatedfiles的目录中的最简单方法。
我一直在尝试不同的方法,但没有一种方法有效。以下命令是我认为最接近的命令。
find ./* -iname "*fast.5" | xargs -I {} ln ./Consolidatedfiles {}
但是我搞乱了ln命令?我有{0}使用find
将xargs
与其他命令配对的经验。
感谢您的帮助!
答案 0 :(得分:5)
以下是最有效的解决方案,用于创建指向单个目标目录中所有文件的硬链接 [1]
,假设您可以使用 GNU ln
,哪个macOS不附带(但您可以通过{安装它) {3}}):
find ./* -iname "*fast.5" -exec ln -t ./Consolidatedfiles/ {} +
macOS 允许使用xargs
(特定于BSD)的高效 -J
解决方案,该解决方案允许定义扩展为(通常)的占位符所有参数,与-0
和find -print0
结合使用,可以有力地传递文件名:
find ./* -iname "*fast.5" -print0 | xargs -0 -J {} ln {} ./Consolidatedfiles/
POSIX兼容解决方案 慢得多,因为它会为每个文件调用ln
:
find ./* -iname "*fast.5" -exec ln {} ./Consolidatedfiles/ \;
请注意 find
的{{1}}如何内置-exec
,只有更强大且效率更高(因为没有管道和单独的需要xargs
个过程):
xargs
就像管道find ... -exec ... {} +
:
(通常)所有参数(尽可能多地适用于单个命令行,使用尽可能少的整体调用)立即传递 ,总是在特定命令的 end 。
请注意,| xargs ...
必须是{}
之前的最后一个参数,这意味着文件名只能在结尾传递命令行。
+
的原因,因为只有它 - 作为Homebrew的扩展 - 允许在 >文件操作数列表,ln
。 -t <dir>
就像管道find ... -exec ... {} ... \;
:
| xargs -I {} ... {} ...
指示的位置,为每个文件调用一次目标命令。使用{}
也比-exec
更健壮,因为文件名总是正确传递,不关心带有空格,引号或嵌入的文件名换行。
xargs
默认情况下将输入流按空格分隔为参数,并且仅使用符合POSIX的选项,不能保证所有参数都正确传递;然而,将xargs
与find -print0
结合起来非常有效,并且Linux(GNU实用程序)和macOS / BSD都支持这两种非标准选项。 谢谢,POSIX spec.。 至于您尝试的内容:
您的 xargs -0
操作数顺序错误; ln
语法为:
ln
所以你应该使用ln <original> <link>
通过该更正,您的命令应该可以正常工作,但出于效率的原因,最好使用基于ln {} ./Consolidatedfiles/
的命令。
[1] 硬链接(与使用-exec
创建的符号链接相对)很少使用,但它们对于安全移动文件分为两个阶段:硬链接指向磁盘上与原始文件完全相同的数据(事实上,即使原始文件是硬链接),所以一旦你确定了在目标位置正确创建了硬链接,您可以安全地删除原始文件(其内容不会丢失,因为新的硬链接仍然指向它们)。