【发布时间】:2012-12-03 16:45:12
【问题描述】:
我有以下命令:
find . -type d -mtime 0 -exec mv {} /path/to/target-dir \;
这会将创建的目录移动到另一个目录。我怎样才能使用xargs 而不是exec 来做同样的事情。
【问题讨论】:
-
为什么要使用
xargs而不是-exec?
我有以下命令:
find . -type d -mtime 0 -exec mv {} /path/to/target-dir \;
这会将创建的目录移动到另一个目录。我怎样才能使用xargs 而不是exec 来做同样的事情。
【问题讨论】:
xargs 而不是-exec?
使用BSD xargs(适用于OS X和FreeBSD),您可以使用为此而构建的-J:
find . -name some_pattern -print0 | xargs -0 -J % mv % target_location
这会将. 中与some_pattern 匹配的任何内容移动到target_location
使用 GNU xargs(对于 Linux 和 Cygwin),请改用 -I:
find . -name some_pattern -print0 | xargs -0 -I % mv % target_location
GNU xargs 已弃用的-i 选项暗示-I{},可以按如下方式使用:
find . -name some_pattern -print0 | xargs -0 -i mv {} target_location
请注意,BSD xargs 也有一个 -I 选项,但它还有其他作用。
【讨论】:
find . -name some_pattern | xargs -I % mv % target_location。谢谢
如果你有 GNU mv(和 find 和 xargs),你可以使用 -t 选项到 mv(和 -print0 到 find 和 -0 到 @ 987654330@):
find . -type d -mtime -0 -print0 | xargs -0 mv -t /path/to/target-dir
请注意,find 的现代版本(与 POSIX 2008 兼容)支持 + 代替 ;,并且在不使用 xargs 的情况下其行为与 xargs 大致相同:
find . -type d -mtime -0 -exec mv -t /path/to/target-dir {} +
这使得find 将方便数量的文件(目录)名称组合到程序的单个调用中。您无法控制xargs 提供的传递给mv 的参数数量,但您实际上很少需要它。这仍然取决于 GNU mv 的 -t 选项。
【讨论】:
-t选项的含义了吗?后面是目标目录名称,这意味着最后一个参数毕竟不是目标,因此完全可以与xargs 一起使用。
-t 误读为xarg 参数。
-print0 和 -0 方法甚至适用于包含换行符的文件名;你的替代方案没有。诚然,很少有文件的名称中包含换行符,但以 null 结尾的符号的意义在于它无一例外地涵盖了所有个文件名。
find ./ -maxdepth 1 -name "some-dir" -type d -print0 | xargs -0r mv -t x/
查找:
使用选项-print0,输出将以'\0'结尾;
xargs:
使用选项-0,它会将args 拆分为'\0' 但空格,-r 表示no-run-if-empty,因此如果find 没有得到任何输出,您将不会收到任何错误。 (-r 是 GNU 扩展。)
当我不确定目标文件是否存在时,我通常在脚本中使用它。
【讨论】:
find 并不是一个很好的工具。我想您想将所有子目录移动到另一个目录中。 find 会输出类似
./a
./a/b
./a/b/c
./a/b/c/d
./a 首先移动后,您只会收到有关“没有这样的文件或目录”所有子目录的错误。
您应该只使用 mv */ /another/place -- 通配符上的尾部斜杠将扩展限制为仅 dirs。
【讨论】:
如果您不使用 GNU mv,则可以使用该命令:
find . -depth -type d -mtime 0 -exec bash -c 'declare -a array;j=1;for i; do array[$j]="$i"; j=$((j+1));done; mv "${array[*]}" /path/to/target-dir' arg0 {} +
否则,这是一个不需要 xargs 的更简单的解决方案:
find . -depth -type d -mtime 0 -exec mv -t /path/to/target-dir {} +
请注意,我添加了 -depth 否则在同时处理目录及其子目录之一时会出现错误。
【讨论】: