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 

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

 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世界中的广泛使用与参数。

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

 echo ~ | xargs ls -A 

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

 find -print 0 | xargs -0 

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

因为你错过了管道字符| 分隔并连接两个命令findxargsfind以为: )xargs是它的一个参数,并且因为它不是以-开始-或者遵循以-开头的有效测试,它决定了)xargs必须是你想要的路径要搜索,但paths must precede expressionfind的语法要求在其他参数之前给出搜索路径。

许多人更喜欢使用-exec with find而不是管道到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 -- {} + 

find: paths must precede expression: )xargsfind: paths must precede expression: )xargs “是find告诉你的方式,因为它正在处理它的参数,它看到的东西看起来像一个起点(实际上,它看起来不像一个表达式)之后以为它已经完成了解析搜索路径,它看到了围绕“ )xargs ”的问题。 man find find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

你已经省略了管道( | )符号来将find的输出连接到xargs的输入。

另一点 – 使用xargs的“ -0 ”选项要求你告诉find用NUL分隔文件名,而不是。- -print0

您是否阅读了我将特定类型/扩展名的文件从一个目录移动到另一个目录的答案? ?