xargs를 사용하여 파일을 찾은 다음 이동하는 방법은 무엇입니까?

xargs를 사용하여 파일을 찾은 다음 이동하는 방법은 무엇입니까?

일부 파일을 찾아서 이동하고 싶습니다.

다음을 통해 파일을 찾을 수 있습니다.

$ 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 -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) ---
.
.
.

답변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( ) 옵션은 --targetGNU에만 적용됩니다. -print0, -r, -0, 비표준 및 GNU 파생 항목도 일부 BSD와 같은 일부 다른 구현에 존재합니다.

POSIX적으로:

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/ {} \;

관련 정보