如何在单个目录中以最少的分叉数量创建符号链接?

发布于 2025-01-14 18:11:28 字数 625 浏览 1 评论 0原文

在以下情况下如何在单个目录中创建符号链接:

  1. 常见方法失败:
ln -s /readonlyShare/mydataset/*.mrc .
# -bash: /bin/ln: Argument list too long
  1. find 命令不允许使用以下语法:
find /readonlyShare/mydataset -maxdepth 1 -name '*.mrc' -exec ln -s {} . +
# find: missing argument to `-exec'
  1. 使用狂野分叉需要数小时才能完成:
find /readonlyShare/mydataset -maxdepth 1 -name '*.mrc' -exec ln -s {} . ';'

How to create symlinks in a single directory when:

  1. The common way fails:
ln -s /readonlyShare/mydataset/*.mrc .
# -bash: /bin/ln: Argument list too long
  1. The find command doesn't allow the following syntax:
find /readonlyShare/mydataset -maxdepth 1 -name '*.mrc' -exec ln -s {} . +
# find: missing argument to `-exec'
  1. Using wild forking takes hours to complete:
find /readonlyShare/mydataset -maxdepth 1 -name '*.mrc' -exec ln -s {} . ';'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

耀眼的星火 2025-01-21 18:11:28
find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -exec ln -s '{}' '+' .

或者如果您更喜欢 xargs

find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -print0 |
  xargs -0 -P0 sh -c 'ln -s "$@" .' sh

如果您使用的是 BSD xargs 而不是 GNU xargs,那么它会更简单:

find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -print0 |
  xargs -0 -J@ -P0 ln -s @ .

为什么 '{} ''+'

引自 man find

-exec utility [argument ...] {} +
             Same as -exec, except that “{}” is replaced with as many pathnames as possible for each invocation of utility.  This behaviour is similar
             to that of xargs(1).  The primary always returns true; if at least one invocation of utility returns a non-zero exit status, find will
             return a non-zero exit status.

find 擅长分割大量参数:

find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -exec ruby -e 'pp ARGV.size' '{}' '+'
15925
15924
15925
15927
1835

为什么不使用 xargs -I

它效率不高而且速度慢,因为 -I 按每个参数执行实用程序,例如:

printf 'foo\0bar' | xargs -0 -I@ ruby -e 'pp ARGV' @
["foo"]
["bar"]
printf 'foo\0bar' | xargs -0 ruby -e 'pp ARGV'
["foo", "bar"]

xargs 也擅长分割大量参数

seq 65536 | tr '\n' '\0' | xargs -0 ruby -e 'pp ARGV.size'
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
536

为什么 sh -c< /代码>?

只有 BSD xargs-J 标志来将参数放在命令中间。对于 GNU xargs,我们需要结合 sh -c"$@" 来完成同样的事情。

find -execfind | xargs

这取决于情况,但我建议当您想利用所有 CPU 时使用 xargsxargs 可以通过 -P 并行执行实用程序,而 find 则不能。

find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -exec ln -s '{}' '+' .

or if you prefer xargs:

find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -print0 |
  xargs -0 -P0 sh -c 'ln -s "$@" .' sh

If you are using BSD xargs instead of GNU xargs, it can be simpler:

find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -print0 |
  xargs -0 -J@ -P0 ln -s @ .

Why '{}' '+'?

Quoted from man find:

-exec utility [argument ...] {} +
             Same as -exec, except that “{}” is replaced with as many pathnames as possible for each invocation of utility.  This behaviour is similar
             to that of xargs(1).  The primary always returns true; if at least one invocation of utility returns a non-zero exit status, find will
             return a non-zero exit status.

find is good at splitting large number of arguments:

find readonlyShare/mydataset -name '*.mrc' -maxdepth 1 -exec ruby -e 'pp ARGV.size' '{}' '+'
15925
15924
15925
15927
1835

Why not xargs -I?

It is not efficient and slow because -I executes the utility per argument, for example:

printf 'foo\0bar' | xargs -0 -I@ ruby -e 'pp ARGV' @
["foo"]
["bar"]
printf 'foo\0bar' | xargs -0 ruby -e 'pp ARGV'
["foo", "bar"]

xargs is also good at splitting large number of arguments

seq 65536 | tr '\n' '\0' | xargs -0 ruby -e 'pp ARGV.size'
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
5000
536

Why sh -c?

Only BSD xargs have -J flag to put arguments in the middle of commands. For GNU xargs, we need the combination of sh -c and "$@" to do the same thing.

find -exec vs find | xargs

It depends but I would suggest use xargs when you want to utilize all your CPUs. xargs can execute utility parallelly by -P while find can't.

許願樹丅啲祈禱 2025-01-21 18:11:28

当我需要它的时候,我很着急,所以我没有探索所有的可能性,但我同时解决了一些问题

感谢@WeihangJian的回答,我现在知道找到... | xargs -I {} ...find ... -exec ... {} ';' 一样糟糕。

我的问题的正确答案是:

find /readonlyShare/mydataset -maxdepth 1 -name '*.mrc' \
    -exec sh -c 'ln -s -- "$@" .' _ {} +

I was in a rush when I needed it so I didn't explore all possibilities but I worked-out something meanwhile

Thanks to @WeihangJian answer I now know that find ... | xargs -I {} ... is as bad as find ... -exec ... {} ';'.

A correct answer to my question would be:

find /readonlyShare/mydataset -maxdepth 1 -name '*.mrc' \
    -exec sh -c 'ln -s -- "$@" .' _ {} +
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文