我有如下一行:
find /foo/bar -name '*.mp4' -print0 | xargs -i {} -0 mv -t /some/path {}
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误:
xargs: argument line too long
Run Code Online (Sandbox Code Playgroud)
我很迷惑。不xargs
应该使用' should'来精确地帮助解决这个问题吗?
注意:我知道我可以在技术上使用-exec
find,但我想了解为什么上述失败,因为我的理解xargs
是应该知道如何将输入拆分为可管理的大小以使其运行的参数。这不是真的吗?
这都是zsh。
slm*_*slm 12
一方面,-i
不推荐使用 switch:
-i[replace-str]
This option is a synonym for -Ireplace-str if replace-str is specified.
If the replace-str argument is missing, the effect is the same as -I{}.
This option is deprecated; use -I instead.
Run Code Online (Sandbox Code Playgroud)
因此,当我将您的命令更改为此时,它起作用了:
$ find /foo/bar -name '*.mp4' -print0 | xargs -I{} -0 mv -t /some/path {}
Run Code Online (Sandbox Code Playgroud)
$ find . -print0 | xargs -I{} -0 echo {}
.
./.sshmenu
./The GIT version control system.html
./.vim_SO
./.vim_SO/README.txt
./.vim_SO/.git
./.vim_SO/.git/objects
./.vim_SO/.git/objects/pack
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.idx
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.pack
./.vim_SO/.git/objects/info
./.vim_SO/.git/refs
./.vim_SO/.git/refs/tags
...
Run Code Online (Sandbox Code Playgroud)
-I{}
由于运行此命令构造,因此不应使用此方法:
$ find -print0 ... | xargs -I{} -0 ...
Run Code Online (Sandbox Code Playgroud)
隐式地将这些开关打开到xargs
、-x
和-L 1
。将-L 1
提供配置xargs
,使得它调用的命令,你想让它通过在一个单一的方式运行的文件。
所以这违背了xargs
在这里使用的目的,因为如果你给它 1000 个文件,它会运行mv
命令 1000 次。
您可以使用 xargs 来做到这一点:
$ find /foot/bar/ -name '*.mp4' -print0 | xargs -0 mv -t /some/path
Run Code Online (Sandbox Code Playgroud)
或者只是找到做这一切:
$ find /foot/bar/ -name '*.mp4' -exec mv -t /some/path {} +
Run Code Online (Sandbox Code Playgroud)
该选项-i
采用可选参数。由于您在 之后放置了一个空格-i
,-i
因此该选项没有参数,因此后续-0
不是选项xargs
而是 6 个操作数中的第二个{} -0 mv -t /some/path {}
。
只有选项-i
, xargs 需要一个换行分隔的文件名列表。由于输入中可能没有换行符,因此 xargs 收到了看起来像一个巨大文件名的内容(带有嵌入的空字节,但 xargs 没有检查)。包含整个输出的单个字符串find
比最大命令行长度长,因此出现“命令行太长”错误。
您的命令将使用-i{}
而不是-i {}
. 或者,您可以使用-I {}
:-I
类似于-i
,但采用强制参数,因此传递给 的下一个参数xargs
用作-I
选项的参数。然后后面的参数 is -0
which 被解释为一个选项,依此类推。
但是,您根本不应该使用-I {}
。使用-I
具有三个效果:
-I
关闭报价处理,这-0
已经做了。-I
更改要替换的字符串,但{}
它是默认值。-I
导致为每个输入记录单独执行命令,这在这里没用,因为您的命令 ( mv -t
) 专门用于处理每次调用的多个文件。无论是下降-I
和-i
完全
find /foo/bar -name '*.mp4' -print0 | xargs -0 mv -t /some/path {}
Run Code Online (Sandbox Code Playgroud)
或删除 xargs 并使用-exec
:
find /foo/bar -name '*.mp4' -exec mv -t /some/path {} +
Run Code Online (Sandbox Code Playgroud)