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
列表解释为以空字符分隔而不是以空格分隔。空字符不能出现在文件名中,因此如果我们使用空字符分隔,则文件名不可能被解释为两个文件名。
由于您错过了|
分隔和连接两个命令的管道符find
和xargs
,find
认为这)xargs
是它的一个参数,并且由于它没有以 开头-
或遵循以 开头的有效测试-
,它决定)xargs
一定是您要搜索的路径,但是paths must precede expression
, 的语法find
要求在其他参数之前给出要搜索的路径。
许多人喜欢使用-exec
withfind
而不是管道 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
告诉你,当它处理参数时,在它认为已经解析完要搜索的路径之后,它看到了一些看起来像起点的东西(实际上,它看起来不像表达式),并且它看到了“ ”周围的问题)xargs
。man find
说find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]
您省略了将 的输出|
连接到的输入的管道符号 ( )。find
xargs
另一点 - 使用“ -0
”选项xargs
需要您要告诉 find 用 s 分隔文件名NUL
,-print0
而不需要用 -。
你读过我的回答吗将特定类型/扩展名的文件从一个目录移动到另一个目录??