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 世界中与参数相关的更广泛的使用.
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
列表解释为空分隔而不是空格分隔。空字符不能出现在文件名中,因此如果我们用空字符分隔,文件名就不可能被解释为两个文件名。
由于您错过了|
分隔和连接两个命令find
and的管道字符xargs
,find
认为这)xargs
是它的参数之一,并且由于它没有以 开头-
或遵循以 开头的有效测试-
,因此它决定)xargs
必须是您要搜索的路径, 但是paths must precede expression
, 的语法find
要求在其他参数之前给出要搜索的路径。
许多人更喜欢使用-exec
withfind
而不是管道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)