【发布时间】:2014-04-18 18:27:36
【问题描述】:
如何通过管道将“查找”的结果(在 Linux 中)移动到不同的目录?这是我目前所拥有的。
find ./ -name '*article*' | mv ../backup
但它还不正确(我收到一个错误缺少文件参数,因为我没有指定文件,因为我试图从管道中获取它)
【问题讨论】:
-
好的,它不完全重复,但也有一个答案:)
如何通过管道将“查找”的结果(在 Linux 中)移动到不同的目录?这是我目前所拥有的。
find ./ -name '*article*' | mv ../backup
但它还不正确(我收到一个错误缺少文件参数,因为我没有指定文件,因为我试图从管道中获取它)
【问题讨论】:
find ./ -name '*article*' -exec mv {} ../backup \;
或
find ./ -name '*article*' | xargs -I '{}' mv {} ../backup
【讨论】:
Powershell 中使用Move-Item Cmdlet。你可以做Move-Item *article* \full\path\to\backup
xargs 常用于此目的,而 Linux 上的 mv 有一个 -t 选项来促进此目的。
find ./ -name '*article*' | xargs mv -t ../backup
如果你的 find 支持 -exec ... \+ 你也可以这样做
find ./ -name '*article*' -exec mv -t ../backup {} \+
-t 选项是一个 GNU 扩展,因此它不能移植到没有 GNU coreutils 的系统上(尽管我见过的每个适当的 Linux 都有这个,可能除了 Busybox)。对于完整的 POSIX 可移植性,当然可以推出您自己的替代品,可能类似于
find ./ -name '*article*' -exec sh -c 'mv "$@" "$0"' ../backup {} \+
我们无耻地滥用sh -c 'commands' 之后的第一个参数作为$0 中的“脚本名称”参数结束的便利事实,因此我们甚至不需要shift 它。
【讨论】:
-exec 的find -- 也许您输入了错误的命令?
我发现在一个文件夹中包含数千个文件非常有用:
ls -U | head -10000 | egrep '\.png$' | xargs -I '{}' mv {} ./png
将前 10000 个文件中的所有 png 移动到子文件夹 png
【讨论】:
egrep(更现代的又名grep -E)语法,您可以分解出head:grep -m 10000 '\.png$',更一般地,您应该avoid ls in scripts,
printf '%s\0' *.png | xargs -r0 mv -t png/ 避免了ls 的各种问题,而printf '%s\0' *.png | grep -z -m 10000 ^ | xargs -r0 mv -t png/ 巧合地使用grep -z -m items 作为head 的替代品以空结尾的输入。我之前发布的链接更详细地解释了这些事情。我对改进主张ls的答案意见不一;但请随意更新您认为合适的内容,并包括来自这些 cmets 的任何内容。顺便说一句,xargs -0 仅适用于 GNU(应该可以在 Linux 上运行,但不能正确移植)。
xargs 是您的好友(当您有多项操作要执行时)!
并且按照我展示的方式使用它也会给你很大的控制权。
find ./ -name '*article*' | xargs -n1 sh -c "mv {} <path/to/target/directory>"
说明:
-n1每个操作需要考虑的行数
sh -c执行的shell命令根据之前的条件给它行
"mv {} /target/path"移动命令将采用两个参数-
1) 操作 1 中的行,即 {},值自动替换
2) 指定的移动命令的目标路径
注意:“双引号”被指定为允许从 xargs 接收参数的 shell 命令使用任意数量的空格或参数
【讨论】:
-n1,那么sh -c 包装器的目的是什么?仅此。与其他较旧的类似答案相比,它带来了缺点。
sh -c 是没有用的。另一方面,-n 1 基本上也使xargs 无用;如果您一次只移动一个文件,只需运行find -exec。但是,一次只处理一个文件是非常浪费的。您通常应该尽量减少子进程的数量。之前的答案实施了各种优化来做到这一点,其中一些比其他的更积极和稳健。
mv $(find . -name '*article*') ../backup
【讨论】:
missing file operand。 (我在 ../backup 之前使用了 -t 来定义目标目录)
找到 . -type f -newermt "2019-01-01" ! -newermt "2019-05-01" -exec mv {} 路径 \;
或
查找路径 -type f -newermt "2019-01-01" ! -newermt "2019-05-01" -exec mv {} 路径 \;
或
找到 /Directory/filebox/ -type f -newermt "2019-01-01" ! -newermt "2019-05-01" -exec mv {} ../filemove/ \;
【讨论】: