我想找到一些文件然后移动它们。
我可以通过以下方式找到该文件:
$ find /tmp/ -ctime -1 -name x*
我尝试将它们移动到我的~/play
目录:
$ find /tmp/ -ctime -1 -name x* | xargs mv ~/play/
但这没有用。显然 mv 需要两个参数。
不确定是否(或如何)在 mv 命令中引用 xargs“当前项目”?
答案1
查看 Stephane 的答案以了解最佳方法,看看我的答案以了解不使用更明显的解决方案的原因(以及它们不是最有效的原因)。
您可以使用以下-I
选项xargs
:
find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/
其工作机制与find
和类似{}
。我还会引用您的-name
论点(因为当前目录中以 开头的文件x
将被文件全局化并作为参数传递给 find - 这不会给出预期的行为!)。
然而,正如 manatwork 所指出的,如xargs
手册页中详细说明的:
-I replace-str
Replace occurrences of replace-str in the initial-arguments with
names read from standard input. Also, unquoted blanks do not
terminate input items; instead the separator is the newline
character. Implies -x and -L 1.
需要注意的重要一点是,这-L 1
意味着只有一个线find
一次将处理的输出。这意味着它在语法上与以下内容相同:
find /tmp/ -ctime -1 -name "x*" -exec mv '{}' ~/play/
(它执行单个mv
操作每个文件)。
即使使用 GNU -0
xargs 参数和find -print0
参数也会导致完全相同的行为-I
- 这是clone()
每个文件的进程mv
:
find . -name "x*" -print0 | strace xargs -0 -I '{}' mv '{}' /tmp/other
.
.
read(0, "./foobar1/xorgslsala11\0./foobar1"..., 4096) = 870
mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbb82fad000
open("/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26066, ...}) = 0
mmap(NULL, 26066, PROT_READ, MAP_SHARED, 3, 0) = 0x7fbb82fa6000
close(3) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fbb835af9d0) = 661
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 661
--- SIGCHLD (Child exited) @ 0 (0) ---
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fbb835af9d0) = 662
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 662
--- SIGCHLD (Child exited) @ 0 (0) ---
.
.
.
答案2
也许这个命令现在是可能的,而在 2013 年还没有,但这对我来说非常有效:
ls pattern* | xargs mv -t DESTINATION/
该-t
键将目标文件夹放在第一位,从而释放mv
命令以将所有最后一个参数仅作为要移动的文件。
答案3
使用 GNU 工具:
find /tmp/ -ctime -1 -name 'x*' -print0 |
xargs -r0 mv -t ~/play/
-t
( )选项--target
是 GNU 特定的。-print0
, -r
, -0
, 而非标准的和源自 GNU 的也存在于其他一些实现中,例如在某些 BSD 上。
POSIXly:
find /tmp/ -ctime -1 -name 'x*' -exec sh -c '
exec mv "$@" ~/play/' sh {} +
两者都根据需要运行尽可能少的mv
命令,并且可以使用文件名可能包含的任何字符。 GNU 可能具有在开始移动第一批文件find
时不断寻找文件的优势。mv
请注意,所有文件和目录最终都将位于一个目录中,如果不同目录中的多个文件具有相同的名称,请注意可能发生冲突。
答案4
您可以尝试使用以下命令并进行测试,效果很好
find /tmp/ -ctime -1 -type f -name "x*" -exec mv -t ~/play/ {} \;