2017-05-04 56 views
1

我正在Mac电脑上使用Bash命令通过终端。巩固成千上万的文件与ln

我有200个目录编号0-200。每个目录包含> 5,000个以.fast5结尾的单个文件。我试图找出将200个目录组中的所有文件合并到一个名为Consolidatedfiles的目录中的最简单方法。

我一直在尝试不同的方法,但都没有工作。下面的命令是我认为最接近的命令。

find ./* -iname "*fast.5" | xargs -I {} ln ./Consolidatedfiles {} 

但是我搞乱了ln命令?我有0经验配对find其他命令使用xargs

感谢您的帮助!

+0

对不起,我感到困惑。我的错误...我的意思是写我想将文件收集到一个目录中。我在上面的问题中纠正了这个问题。 – Paul

+0

还有一个问题:所有的旧文件应该移动到新的目录或刚刚复制? – RomanPerekhrest

+1

而不是移动或复制文件我虽然使用ln链接到新目录中的原始文件将是最好的解决方案。 – Paul

回答

5

下面是在一个单一的目标目录中创建硬链接到您的所有文件的最有效的解决方案[1] ,假设你可以使用GNUln这MacOS的不配备(你可以,但是,通过Homebrew安装):

find ./* -iname "*fast.5" -exec ln -t ./Consolidatedfiles/ {} + 

MACOS允许有高效xargs溶液-J(BSD特异性),其允许定义一个占位符,扩展为(典型地)所有参数,与-0find -print0组合以鲁棒地传递文件名:

find ./* -iname "*fast.5" -print0 | xargs -0 -J {} ln {} ./Consolidatedfiles/ 

A-POSIX兼容解决方案慢得多,因为它调用ln为每个文件:

find ./* -iname "*fast.5" -exec ln {} ./Consolidatedfiles/ \; 

注意如何find-exec就像一个内置xargs,只有更健壮以及更高效的(因为不需要管道和独立xargs过程):

  • find ... -exec ... {} +像管道到| xargs ...

    • (通常)所有参数(尽可能多地适合单个命令行,尽可能少地使用调用)通过立即,总是在特定命令的处。

    • 注意{}必须+前的最后一个参数,这意味着该文件名只能在命令行的年底传递。

      • 这就是为什么GNUln以上要求,因为只有它 - 作为扩展到POSIX spec. - 允许前指定的目标目录文件操作数的列表,-t <dir>
  • find ... -exec ... {} ... \;是像管道到| xargs -I {} ... {} ...

    • 目标命令为每个文件调用一次,与{}所示的位置。
  • 使用-exec也较为强劲xargs,因为文件名总是正确传递,有关于与空格,引号,甚至嵌入式换行符的文件名没有顾虑。

    • 相比之下,xargs默认由空格打破输入流中的参数,并使用POSIX兼容的唯一选择,你不能保证所有的参数都正确地传递;然而,find -print0xargs -0的结合非常稳健,而且这两个非标准选项在Linux(GNU实用程序)和macOS/BSD上均受支持。 谢谢,Charles Duffy

至于你试过

ln操作数顺序错误;该ln语法是:

ln <original> <link> 

,所以你应该使用ln {} ./Consolidatedfiles/

随着该修正你的命令应该工作,但是使用基于命令以上优先效率的原因-exec


[1] 链路(相对于与ln -s创建的符号链接)都很少不再使用,但它们是在2个阶段安全移动文件有用:硬链接指向到与原始文件完全相同的数据(实际上,甚至是原始文件都是硬链接),因此一旦确定硬链接在目标位置正确创建,就可以安全地删除原始文件(其内容不会丢失,因为新的硬链接仍指向它们)。

+0

还有一个非常高效的Perl版本,可避免为每个文件创建一个进程...'find ... -print0 | perl -n0e'ln ...'' –

+0

@MarkSetchell:我假设你的意思是'link'(Perl函数)而不是'ln' - 这是一个选项,但它需要更多的工作,因为'link'不接受目标_directory_作为第二个参数。 原来,在macOS上结合'find -print0'和'xargs -0 -J {}'可能是最好的选择 - 查看我的更新。 – mklement0