매개변수로 파일 경로를 요구하는 프로그램이 있는데, 이 경로는 인용할 수 없고 작업 디렉토리에 의존할 수 없습니다. 여러 개의 xargs
, tr
, find
, s를 연결하지 않고 이 작업을 수행할 수 있습니까 readlink
?
"*.csv" 파일의 출력 예:/home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv
답변1
파일 경로를 명령에 인수로 전달하려면,find
너 스스로해라-exec
옵션트릭 없음 xargs
:
find /home/user -name '*.csv' -exec yourcommand '{}' +
그러면 호출된 모든 파일을 찾은 *.csv
다음 발견된 모든 파일을 인수로 실행합니다. 발견된 각 파일은 별도의 전체 인수로 프로그램에 전달되므로 이스케이프나 기타 다른 작업이 필요하지 않습니다. 각 인수는 전체 파일 경로인 많은 인수를 사용합니다./home/user
yourcommand /home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv ...
yourcommand
또 다른 방법은 쉘(zsh
특히)는 다음과 같이 작성할 수 있는 고급 와일드카드를 지원합니다.
yourcommand **/*.csv
위와 같은 효과도 얻을 수 있습니다.
문자열 자체를 정말로 이스케이프 처리하고 싶다면, 명령을 직접 실행하는 대신 bash
'를 사용할 수 있습니다.내장printf
:
find /home/user -name '*.csv' -exec bash -c 'printf "%q " "$@"' dummy '{}' +
형식 %q
사양은 문자열 인수의 셸 이스케이프 버전으로 확장됩니다. 많은 매개변수의 경우 printf
형식 문자열이 모든 매개변수에 대해 반복되므로 명령의 모든 매개변수에 대해 공백으로 끝나는 이스케이프 문자열이 생성됩니다 bash -c
. dummy
의 값으로 사용 $0
하고 (전체) 파일 이름인 나머지 인수를 모두 "$@"
제공합니다 . printf
귀하의 예에서는 정확히 /home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv
.
답변2
그리고 zsh
:
print -r -- **/*.csv(D:a:q)
줄 바꿈, 탭 또는 인쇄할 수 없는 문자와 같은 일부 문자는 기호를 사용하여 렌더링되므로 $'...'
문제가 될 수 있습니다.
또 다른 방법은 다음과 같습니다.
print -r -- *.csv(e/'REPLY=${(qq)REPLY:a}'/)
모든 파일 경로는 작은따옴표로 묶입니다.