이 장소표준 입력을 명령 인수의 원하는 위치에 전달할 수 있는 옵션 xargs
과 함께 명령을 제공합니다 .-J
find . -name '*.ext' -print0 | xargs -J % -0 rsync -aP % user@host:dir/
하지만 한 번에GNU xargs 매뉴얼 페이지이 옵션은 존재하지 않습니다.
이것을 허용하는 명령에 대해 이를 수행하는 방법은 무엇입니까?
답변1
이것이 당신이 기대했던 것인지는 확실하지 않지만 BSD 세계(예: macOS)에서는 여러 "줄"을 명령에 전달하는 방법이 다릅니다 -I
. -J
예:
$ ls
file1 file2 file3
$ find . -type f -print0 | xargs -I % rm %
rm file1
rm file2
rm file3
$ find . -type f -print0 | xargs -J % rm %
rm file1 file2 file3
따라서 를 사용하면 -I
xargs는 전달된 각 요소에 대해 개별적으로 명령을 실행합니다. 를 사용하면 -J
xargs는 명령을 한 번 실행하고 모든 요소를 연결하여 모두 함께 인수로 전달합니다.
rm
또는 같은 일부 명령은 mkdir
여러 인수를 취하고 단일 인수를 전달하고 여러 번 실행한 것과 동일한 방식으로 작동할 수 있습니다. 그러나 일부 앱은 인수를 전달하는 방법에 따라 변경될 수 있습니다. 예를 들어 tar
. tar 파일을 생성한 다음 파일을 추가하거나 모든 파일을 한 번에 추가하여 tar 파일을 생성할 수 있습니다.
$ find . -iname "*.txt" -or -iname "*.pdf" -print0 | xargs -0 -J % tar cjvf documents.tar.bz2 %
답변2
이것이 -J
BSD 버전의 플래그 라면 xargs
GNU와 정확히 동등한 옵션이 있다고 생각하지 않습니다 xargs
. -J
단일 발생을 대체합니다.응답자(예: %
) 각 행은 표준 입력을 통해 들어옵니다. GNU 버전에는비슷한그러나 옵션은 다음과 같습니다. -I
1 . 그러나 다음을 사용할 수 있습니다.응답자해당 플래그를 사용하여 여러 번.
명령 호출이 하나인지 여러 개인지가 중요하지 않은 사용 사례에서는 GNU를 xargs -I
즉시 대체할 수 있습니다. 그러나 귀하의 예에서는 rsync
이를 여러 번 호출하는 것을 원하지 않을 것이라고 확신합니다.
그러면 최선의 조치는 find
및 -exec
또는 -execdir
조치로 시작하는 대안을 고려하는 것입니다. 여기에는 두 가지 변형이 있습니다. 하나는 GNU와 유사 -I
하고 다른 하나는 BSD와 유사합니다 -J
. 이 예들을 살펴보세요...
# Note the escaping of ';'
$ find /tmp -name '*.txt' -exec echo {} \;
/tmp/a.txt
/tmp/b.txt
..
/tmp/z.txt
이제 이를 다음과 비교해 보세요.
$ find /tmp -name '*.txt' -exec echo {} +
/tmp/a.txt /tmp/b.txt .. /tmp/z.txt
둘 사이의 유일한 차이점은 끝에 "수정자"가 나타나는 것 +
입니다 ;
.
1 더 혼란스러운 점은 BSD 버전에도 기능이 있고 GNU와 -I
기능이 비슷하다는 것입니다 ! 그러나 이는 다른 플래그의 영향을 받으며 원하는 플래그가 아닐 가능성이 높습니다.-J
-I
-I