查找:路径必须在表达式之前:)xargs

Jac*_*ite 0 command-line bash directory find xargs

mkdir dregsfolder
find /home/tony/Desktop/unsorted_files/ -maxdepth 1 -not \( -type d -or -iname "*.jpg" -or -iname "*.gif" -or -iname "*.docx" \)xargs -0 --no-run-if-empty mv /home/tony/Desktop/dregsfolder
Run Code Online (Sandbox Code Playgroud)

当我运行该代码时;我被告知

find: paths must precede expression: )xargs
Run Code Online (Sandbox Code Playgroud)

我很困惑,因为我认为路径已经用/home/tony/Desktop/unsorted_files.

我更加困惑,因为在Unix & Linux Stack Exchange 上的这个问题中,我们有一个xargs将文件复制到名为 的目录的示例play

find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/
Run Code Online (Sandbox Code Playgroud)

而这里,似乎是目标目录,即播放;已在xargs...之后指定

我想澄清与之相关的精确机制xargs和其中的细微差别,不仅要解析目录中的文件(如上一个问题中所述),而且还要解析它在 unix 世界中与参数相关的更广泛的使用.

Zan*_*nna 5

xargs尝试从其标准输入(标准输入)构造参数列表。通常, 的标准输入xargs是某些已通过管道传输到 的命令的输出xargs。为了创建一个无用的例子,我们可以浪费很多字符来列出我们主目录中的文件,而不是ls -A ~像这样输入:

echo ~ | xargs ls -A
Run Code Online (Sandbox Code Playgroud)

管道操作符|将命令的 stdout(标准输出)放在它的左边,并将它作为命令的 stdin 传递到它的右边。重要的是要记住 stdout 只是一个文本流,xargs如果它包含空格或特殊字符,则在传递给第二个命令时可能会导致问题。当我们使用find,其输出为文件名,与 时xargs,为了避免特殊字符导致的错误,我们通常使用

find -print 0 | xargs -0
Run Code Online (Sandbox Code Playgroud)

这导致find将空字符附加到每个文件名并将xargs列表解释为空分隔而不是空格分隔。空字符不能出现在文件名中,因此如果我们用空字符分隔,文件名就不可能被解释为两个文件名。

由于您错过了|分隔和连接两个命令findand的管道字符xargsfind认为这)xargs是它的参数之一,并且由于它没有以 开头-或遵循以 开头的有效测试-,因此它决定)xargs必须是您要搜索的路径, 但是paths must precede expression, 的语法find要求在其他参数之前给出要搜索的路径。

许多人更喜欢使用-execwithfind而不是管道xargs(请参阅find with -exec 和 xargs 之间的区别是什么?),例如:

find /path -tests ... -exec some_command {} +
Run Code Online (Sandbox Code Playgroud)

这可能更适合您的情况,特别是因为该mv命令期望其最后一个参数是目标。您可以使用,xargs -I {} mv {} /path/to/destination但使用-t

find /home/tony/Desktop/unsorted_files/ -maxdepth 1 -not \( -type d -or -iname "*.jpg" -or -iname "*.gif" -or -iname "*.docx" \) -exec mv -t /home/tony/Desktop/dregsfolder -- {} +
Run Code Online (Sandbox Code Playgroud)