여러 값이 포함된 옵션을 사용하는 CLI 도구가 있습니다. 구문은 다음과 같습니다.
CLI -I path/to/file1 -I path/to/file2 ...
find
명령 결과를 이 CLI에 어떻게 전달합니까 ?
참고로
위치 매개변수가 여러 개인 경우:
CLI path/to/file1 path/to/file2 ...
저 할 수 있어요:
find "dir" -name "pattern" -exec CLI {} \+
답변1
zsh
전환이 옵션인 경우 다음을 통해 쉽게 수행할 수 있습니다.
CLI **/pattern(P[-I])
여기서 P
glob 한정자는 P
일치하는 각 파일의 접두사로 매개변수를 삽입하는 데 사용됩니다.
ksh 스타일 프로세스 교체를 지원하는 GNU find
및 xargs
zsh 또는 bash와 같은 셸을 사용하면 다음을 수행할 수도 있습니다.
xargs -xr0 -n100 -a <(find . -name pattern -printf '-I\0%p\0') CLI
100
여기에서는 인수 목록이 단일 호출에 맞도록 충분히 작은 짝수를 선택합니다 CLI
. 이것이 없으면 xargs
목록을 -I
다음 파일 로 분할할 수 있습니다 p
. 여전히 해당 제약 조건을 충족하지 않으면 더 적은 수의 인수로 실행하는 대신 -n 100
종료됩니다 .-x
xargs
CLI
이 외에도 동의하는 경우 CLI
다음을 수행할 수도 있습니다.-Ipath/to/file
-I path/to/file
find . -name pattern -exec bash -c '
exec CLI "${@/#/-I}"' bash {} +
이는 필요한 경우 여러 번 호출하여 매개변수 크기 제한을 해결하기 위한 것이지만 -exec cmd {} +
, bash는 각 매개변수에 를 추가하므로 자체적으로 실행될 때 여전히 해당 제한에 도달할 수 있습니다.cmd
-I
cmd
그러나 해당 접두사는 -I
모든 파일 경로에 추가된 접두사와 길이가 정확히 같고 ./
여기서는 필요하지 않으므로 bash
이를 ./
다음으로 대체하여 -I
문제를 완전히 피할 수도 있습니다.
find . -name pattern -exec bash -c '
exec CLI "${@/#.\//-I}"' bash {} +
( .
그 자체(시작 파일)가 다음과 같다고 가정합니다.무늬).
위의 방법은 시스템 호출 제한 사항을 zsh
해결하려고 시도하지 않으며 한 번만 execve()
실행되거나 CLI
전혀 실행되지 않습니다. zargs
자동 로드 기능을 사용하여 이 제한 사항을 해결할 수 있습니다 .
CLI
파일당 한 번만 호출하는 것이 중요 하다면 -I file
최신 버전의 Linux에서는 스택 크기 제한을 늘리는 것이 limit stacksize 100M
도움이 됩니다(예: zsh의 기본값인 8MiB에서). execve()
제한은 스택 크기 제한에 비례하기 때문입니다.
답변2
CLI
출력에서 매개변수 배열을 생성하고 각 파일 이름을 앞에 붙인 후 find
다음 매개변수를 사용하여 호출합니다.-I
CLI
#!/usr/bin/env bash
args=()
while IFS= read -r file; do
args+=( -I "$file" )
done < <(find "dir" -name "pattern" -print)
CLI "${args[@]}"
파일 이름에 개행 문자가 포함될 수 있는 경우(질문의 예와 달리) -d ''
매개변수 에 추가 read
하고 GNU를 사용 find
하여 .-print
-print0
위 가정의 내용은 args[]
ARG_MAX를 초과하지 않습니다.
답변3
첫 번째 시도로,
find . -print | sed 's/^/-I /'| xargs echo
할 것입니다. 경고: 파일 이름에 공백 및/또는 특수 문자와 관련된 문제가 많이 있습니다.