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

查找:路径必须位于表达式之前:)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

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

find: paths must precede expression: )xargs

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

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

find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/

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

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

答案1

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

echo ~ | xargs ls -A

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

find -print 0 | xargs -0

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

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

许多人喜欢使用-execwithfind而不是管道 to xargs(见find 与 -exec 和 xargs 有什么区别?), 例如:

find /path -tests ... -exec some_command {} +

这可能更适合您的情况,特别是因为该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 -- {} +

答案2

find: paths must precede expression: )xargs” 是find告诉你,当它处理参数时,在它认为已经解析完要搜索的路径之后,它看到了一些看起来像起点的东西(实际上,它看起来不像表达式),并且它看到了“ ”周围的问题)xargsman findfind [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

您省略了将 的输出|连接到的输入的管道符号 ( )。findxargs

另一点 - 使用“ -0”选项xargs 需要您要告诉 find 用 s 分隔文件名NUL-print0而不需要用 -。

你读过我的回答吗将特定类型/扩展名的文件从一个目录移动到另一个目录?

相关内容