나는 보았다'find -exec cmd {} +'가 '{} +'로 끝나야 하는 이유는 무엇입니까?이것은 (*) 끝에 {} +
있어야 하는 이유를 설명합니다. 이제 GNU가 입력 인수당 하나의 명령으로 되돌아가는 이유가 무엇인지 궁금합니다 -exec cmd
.xargs
-I
-i
-I는 -str [...]을 대체하여 -x 및 -L 1을 의미합니다.
예를 들어:
$ seq 1 10 | xargs echo
1 2 3 4 5 6 7 8 9 10
$ seq 1 10 | xargs -I {} echo {}
1
2
3
4
5
6
7
8
9
10
xargs 매뉴얼 페이지의 BUGS 섹션에는 다음과 같이 간단히 설명되어 있습니다.
-L 옵션은 -I 옵션과 호환되지 않지만 호환되어서는 안 됩니다.
그리고
-I 옵션을 사용하면 입력에서 읽은 각 행이 내부적으로 버퍼링됩니다. 이는 -I 옵션과 함께 사용할 때 xargs가 허용하는 입력 행의 길이에 상한이 있음을 의미합니다. 이 제한 사항을 해결하려면 -s 옵션을 사용하여 xargs에서 사용하는 버퍼 공간의 양을 늘릴 수 있으며 xargs에 대한 추가 호출을 사용하여 매우 긴 줄이 발생하지 않도록 할 수도 있습니다.
이유도 설명하지 않습니다.
사용하는 주요 이유 중 하나 xargs
는 실행되는 명령 수를 줄이는 것입니다( cp
각각 1000개의 소스 파일 이름을 실행하거나 1개의 소스 파일 이름을 사용하는 것보다 하나를 실행하거나 1000개의 소스 파일 이름을 사용하는 것이 더 좋습니다 mv
). UNIX 명령에서는 소스(예: 파일 목록)가 대상(예: 디렉터리) 앞에 와야 합니다.cp
mv
그렇다면 왜 xargs
그러한 제한이 있습니까?
업데이트 날짜: 2015-11-05
최근에 freebsd 10.0 VM을 만들었고 freebsd 버전에 이 문제를 처리할 수 있는 옵션이 xargs
있다는 것을 발견했습니다.-J
-J 응답자
이 옵션을 지정하면 xargs는 해당 데이터를 다른 모든 인수에 추가하는 대신 첫 번째 replstr 발생을 표준 입력에서 읽은 데이터로 바꿉니다. 이 옵션은 입력에서 읽은 인수 수(-n) 또는 xargs가 생성하는 명령의 크기(-s)에 영향을 주지 않습니다. 이 옵션은 실행된 명령에서 해당 매개변수가 배치될 위치를 단순히 이동합니다. replstr은 xargs에 대한 별도의 인수로 나타나야 합니다. 예를 들어, 인용된 문자열 중간에 있으면 인식되지 않습니다. 또한 처음으로 나타나는 replstr만 교체됩니다. 예를 들어, 다음 명령은 현재 디렉터리에서 대문자로 시작하는 파일 및 디렉터리 목록을 destdir에 복사합니다.
/bin/ls -1d [A-Z]* | xargs -J % cp -Rp % destdir
(*) 본질적으로 "POSIX 사양에 그렇게 나와 있기 때문입니다". 내가 보기에는 그들은 의 {}
어느 곳에나 나타날 수 있는 솔루션을 찾기 위해 더 열심히 노력해야 하거나 -exec ... +
최소한 cp 및 mv와 같은 표준 도구를 사용하여 -t
GNU와 같은 옵션을 사용하여 소스와 대상을 반대로 해야 할 것 같습니다.
답변1
(이것은 질문에 대한 답변이 아니기 때문에 주석이어야 하지만 너무 길기 때문에 주석으로 처리하십시오.)
FreeBSD xargs 대신 이러한 제한이 없는 GNU Parallel을 사용할 수 있습니다. 반복되는 컨텍스트도 지원합니다.
seq 10 | parallel -Xj1 echo con{}text
seq 10 | parallel -mj1 echo con{}text
GNU Parallel은 동일한 컴퓨터 또는 SSH를 통해 액세스할 수 있는 여러 컴퓨터에서 작업을 병렬로 쉽게 실행할 수 있게 해주는 범용 병렬 처리기입니다. 종종 for
루프를 대체할 수 있습니다.
4개의 CPU에서 32개의 서로 다른 작업을 실행하려는 경우 병렬화하는 간단한 방법은 각 CPU에서 8개의 작업을 실행하는 것입니다.
대신, GNU Parallel은 작업이 완료되면 새로운 프로세스를 생성하여 CPU를 활성 상태로 유지하여 시간을 절약합니다.
설치하다
배포판에 GNU Parallel이 패키지되어 있지 않으면 루트 액세스 없이 개인 설치를 수행할 수 있습니다. 이 작업은 10초 안에 완료할 수 있습니다.
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
다른 설치 옵션은 다음을 참조하세요.http://git.savannah.gnu.org/cgit/parallel.git/tree/README
더 알아보기
더 많은 예시 보기:http://www.gnu.org/software/parallel/man.html
소개 비디오 보기:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
이 튜토리얼을 살펴보세요:http://www.gnu.org/software/parallel/parallel_tutorial.html
지원을 받으려면 이메일 목록에 가입하세요.https://lists.gnu.org/mailman/listinfo/parallel
답변2
POSIX는 사물을 정의하지 않으며 POSIX는 표준이 되기 위해 기존 구현을 설명할 뿐입니다.
find -exec +는 David Korn이 1989년 SVr4용으로 도입한 것으로, 매우 늦게 표준에 추가되었기 때문에 변경할 기회가 거의 없었습니다.
그러나 현재 표준에는 문제가 없습니다. 언제든지 다음을 호출할 수 있습니다.
find . -type f -exec sh -c 'somecommand "$@" somedir' sh {} +
따라서 제한이 없으며 비표준 옵션을 사용할 필요가 없음을 알 수 있습니다.
xargs 관련: 공급업체별 구현의 내부에 대해 질문하고 있습니다. 분명히 공급업체별 구현 작성자가 여기에서 읽고 쓰지 않는 한 여기에서 질문에 대한 유용한 답변을 얻을 수 없을 것입니다.
그러나 내 예는 xargs에서도 유사하게 작동합니다.