파일을 찾은 다음 xargs를 사용하여 파일을 이동하려면 어떻게해야합니까?


28

파일을 찾은 다음 이동하고 싶습니다.

파일을 찾을 수 있습니다 :

$ find /tmp/ -ctime -1 -name x*

다음을 사용하여 ~/play디렉토리 로 이동하려고했습니다 .

$ find /tmp/ -ctime -1 -name x* | xargs mv ~/play/

그러나 그것은 효과가 없었습니다. 분명히 mv에는 두 가지 인수가 필요합니다.
mv 명령에서 xargs '현재 항목'을 참조하는지 (또는 방법) 확실하지 않습니까?


3
왜? 플레이스 홀더를 -I: 와 함께 사용할 수 find . | xargs -I'{}' mv '{}' ~/play/있지만, 사람이 말했듯이“Implies -xand -L 1”. 따라서 아무런 이득이 없습니다. 더 나은은 간단하고 사용 유지find . -exec mv '{}' ~/play/ \;
manatwork

마음에 들지 않으면 투표를 보려면 답변으로 게시하십시오 :)
Michael Durrant

내가 요점을 얻지 못했다는 느낌이 들기 때문에 당신의 이유를 물었습니다. Drav Sloan이 묵시적 옵션에 메모를 추가하면 그의 답변은 내가 쓸 수있는 최선의 결과 일 것입니다. 따라서 더 잘 진행하십시오.
manatwork

의 중복 가능성 찾기 패턴과 이동
SLM

나는 그 점 duder :) 반영하기 위해 내 대답은 편집 한 @manatwork
Drav 슬로 언

답변:


43

가장 좋은 방법에 대한 Stephane의 답변을보고 더 명확한 솔루션을 사용하지 않는 이유와 가장 효율적인 방법이 아닌 이유에 대한 내 대답을 살펴보십시오.

다음 -I옵션을 사용할 수 있습니다 xargs.

find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/

어떤 유사한 메커니즘으로 작동 find하고 {}. 또한 현재 디렉토리에서 -name시작하는 파일 x은 파일을 glob하고 찾기위한 인수로 전달되기 때문에 예상 한 동작을 제공하지 않기 때문에 인수를 인용합니다 .

그러나 manatwork에서 지적한대로 xargsman 페이지에 자세히 설명되어 있습니다 .

   -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정확히 동일한 동작이 발생 합니다 . 이는 각 파일 -Iclone()대한 프로세스입니다 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) ---
.
.
.

파일 이름에 줄 바꿈, 작은 따옴표, 큰 따옴표 또는 백 슬래시 문자가 포함되어 있지 않다고 가정합니다.
Stéphane Chazelas

17

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은 첫 번째 배치 이동 을 시작 하면서 파일 을 계속 찾고 있다는 이점이 있습니다.

모든 파일과 디렉토리가 하나의 디렉토리에있게되고, 다른 디렉토리에있는 여러 파일의 이름이 같은 경우 충돌에주의하십시오.


이 솔루션은 mv모든 인수 (또는 제공된 경우 -L또는 모두)를 한 번만 호출하므로 성능이 훨씬 뛰어납니다 -n. 그렇지 않으면 mv각 파일을 호출 하면 오래되고 느려집니다.
r2evans

1

아마도이 명령은 지금 가능하며 2013 년에는 없었지만 이것이 완벽하게 작동합니다.

ls pattern* | xargs mv -t DESTINATION/

-t키는 대상 폴더를 맨 앞에두고 mv이동하는 파일처럼 모든 마지막 인수를 갖도록 명령을 해제합니다 .


1
이것은 나를 위해 일한 가장 간단한 솔루션이었습니다
ptetteh227

0

아래 명령으로 시도하고 테스트 할 수 있으며 정상적으로 작동합니다.

find /tmp/ -ctime -1 -type f -name "x*" -exec mv -t ~/play/ {} \;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.