如何找到文件然后使用 xargs 移动它们?

Mic*_*ant 45 find xargs rename

我想找到一些文件然后移动它们。

我可以找到该文件:

$ find /tmp/ -ctime -1 -name x*
Run Code Online (Sandbox Code Playgroud)

我尝试将它们移动到我的~/play目录中:

$ find /tmp/ -ctime -1 -name x* | xargs mv ~/play/
Run Code Online (Sandbox Code Playgroud)

但这没有用。显然 mv 需要两个参数。
不确定是否(或如何)在 mv 命令中引用 xargs“当前项目”?

Dra*_*oan 58

看看 Stephane 的最佳方法的答案,看看我的答案,看看我为什么不使用更明显的解决方案(以及它们不是最有效的原因)。

您可以使用以下-I选项xargs

find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/
Run Code Online (Sandbox Code Playgroud)

它的工作机制与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.
Run Code Online (Sandbox Code Playgroud)

需要注意的重要一点是,这-L 1意味着一次只会处理一行输出find。这意味着它在语法上与:

find /tmp/ -ctime -1 -name "x*" -exec mv '{}' ~/play/
Run Code Online (Sandbox Code Playgroud)

mv每个文件执行一个操作)。

即使使用 GNU -0xargs 参数,该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) ---
.
.
.
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 21

使用 GNU 工具:

find /tmp/ -ctime -1 -name 'x*' -print0 |
  xargs -r0 mv -t ~/play/
Run Code Online (Sandbox Code Playgroud)

-t--target)选项是GNU具体。-print0, -r, -0, 而非标准的和起源于 GNU 也可以在其他一些实现中找到,比如在一些 BSD 上。

POSIXly:

find /tmp/ -ctime -1 -name 'x*' -exec sh -c '
  exec mv "$@" ~/play/' sh {} +
Run Code Online (Sandbox Code Playgroud)

两者都mv根据需要运行尽可能少的命令,并处理文件名可能包含的任何字符。GNU 可能具有findmv开始移动第一批文件时继续查找文件的优势。

注意所有文件和目录最终都会在一个目录中,如果不同目录中的多个文件具有相同的名称,请注意冲突。


Nik*_* VJ 16

也许这个命令现在是可能的,而不是在 2013 年,但这对我来说非常有效:

ls pattern* | xargs mv -t DESTINATION/
Run Code Online (Sandbox Code Playgroud)

-t关键的看跌期权的目标文件夹第一,释放mv命令将所有最后论据只是将文件移动。

  • 这是对我有用的最简单的解决方案 (2认同)