glob과 재귀적으로 일치하는 공백으로 구분되고 이스케이프된 파일 전체 경로를 구성하는 방법은 무엇입니까?

glob과 재귀적으로 일치하는 공백으로 구분되고 이스케이프된 파일 전체 경로를 구성하는 방법은 무엇입니까?

매개변수로 파일 경로를 요구하는 프로그램이 있는데, 이 경로는 인용할 수 없고 작업 디렉토리에 의존할 수 없습니다. 여러 개의 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/useryourcommand /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}'/)

모든 파일 경로는 작은따옴표로 묶입니다.

관련 정보