파일의 와일드카드 패턴을 큰따옴표로 묶는 방법은 무엇입니까?

파일의 와일드카드 패턴을 큰따옴표로 묶는 방법은 무엇입니까?

이와 비슷한 질문을 많이 봤지만 똑같은 질문은 없었습니다.

와일드카드 확장을 사용하여 단일 큰따옴표 인수로 명령에 전달하려는 파일 디렉터리가 있습니다.

문서

a.ext
b.ext
c.ext

필수 사용

command --flag "a.ext b.ext c.ext"

현재 사용 중이지만 command --flag $(echo \"$(echo ./*.ext)\")작동하지 않고 불필요하게 복잡한 것 같습니다. 이를 수행하는 쉬운 방법이 있습니까?

답변1

SPC 문자 확장 글로브로 생성된 파일 이름을 연결하려면 이를 위치 매개변수에 저장하고 이를 사용하여 "$*"연결할 수 있습니다.

set -- ./*.ext
IFS=' ' # SPC is the first character of $IFS by default, we're setting it
        # here in case that code is called in a context where it has been
        # modified before.
files_joined_with_SPC="$*"
cmd --flag "$files_joined_with_SPC"

또는:

cmd --flag "$*"

물론 직접적으로(현재 값에 따라 달라진다는 사실을 잊는 것이 더 쉽지만 $IFS).

위의 내용은 표준 POSIX sh구문입니다. zsh// ksh93// bash/ 에서는 위치 인수 대신 배열을 사용할 수도 있습니다 mksh.yash

files=(./*.ext)
IFS=' '; files_joined_with_SPC="${files[*]}"

Pass zsh, 다음을 사용할 수도 있습니다.

files=(./*.ext)
cmd --flag "${(j[ ])files}"

또는 익명 함수를 사용하십시오.

(){ cmd --flag "${(j[ ])argv}"; } ./*.ext

j다음과 같은 전역 매개변수 $IFS에 의존하지 않고 SPC 사용을 명시적으로 요청합니다 .

이제 SPC는 파일 경로의 모든 문자로 유효합니다. NUL을 제외한 파일 경로의 모든 문자가 유효합니다(실제로는 모든 문자).바이트 값대부분의 시스템에서 0인 경우 이러한 바이트는 유효한 문자를 형성할 필요조차 없지만 다음 명령에 대한 인수로 NUL을 전달할 수 없습니다.처형된.

당신은 그것이 무엇인지 말하지 않습니다command예(덧붙여서 이것은 자리 표시자로 command사용하기를 선호하는 표준 쉘 내장의 이름입니다 ). 그러나 이것이 파일 이름 목록(SPC로 구분됨)을 허용하려는 경우 사용자가 다음에서 지정할 수 있는 방법이 있어야 합니다. 파일 이름.cmdcmd --flag listSPC

이는 cmd --flag 'with\ space.ext other.ext'또는 등이 될 수 있습니다 cmd --flag 'with%20space.ext other.ext.cmd --flag 'with\040space.ext other.ext'

이 경우 매개변수를 구성할 때 다음을 cmd --flag수행해야 할 수도 있습니다.탈출하다SPC와 연결하기 전에 파일 이름에 \SPC(및 가능한 문자)를 포함하십시오 .%

ksh93// zsh/ 에서는 bash다음을 yash수행할 수 있습니다.

escaped_files=("${files[@]//\\/\\\\}") # \ escaped as \\
escaped_files=("{files[@]// /\\ }")    # SPC escaped as \SPC
# more characters may need to be escaped such as other whitespace
# or quoting characters, depending on the exact syntax expected by
# cmd for the --flag option.

IFS=' '; escaped_files_joined_with_SPC="$*"
cmd -- flag "$escaped_files_joined_with_SPC"

(GB18030, BIG5 등과 같은 문자 인코딩을 사용하는 로케일에는 이러한 문자 중 일부에 백슬래시 인코딩(바이트 0x5c)이 포함되어 있다는 점에 유의하십시오. 쉘은 이러한 0x5c 바이트를 이스케이프할 수 없지만 cmd --flag디코딩되지 않으면 여전히 처리될 수 있습니다. 로캘의 문자 집합에 따라 백슬래시 인수로 사용됨)

보다 안정적이고 편리한 명령 방법을 얻을 수 있습니다.목록파일 이름은 별도의 인수(따라서 옵션에 대한 인수가 아님) 또는 cmd --flag 'file 1.ext' --flag 'file 2.ext'....

답변2

인용된 문자열로 모든 파일 이름을 얻으려면:

command --flag "$(echo ./*.ext)"

아시다시피 이는 단순한 파일 이름에서만 작동합니다. 이는 파일 이름에 공백이 없음을 의미합니다. 값에 따라 xpg_echo백슬래시가 없음을 의미할 수도 있습니다(힌트:선행).

답변3

glob 확장 파일에 대한 for 루프를 설정합니다. var라는 쉘 변수를 파일 이름의 컨테이너로 사용하십시오. 각 반복마다 쉘 변수 var를 업데이트합니다.

var=
for f in *.ext; do var=${var-}${var:+ }$f; done
your_command --flag "$var"

관련 정보