Bash 스크립트의 이스케이프 공백이 작동하지 않습니다.

Bash 스크립트의 이스케이프 공백이 작동하지 않습니다.

내가 시도한 것은 아무것도 작동하지 않았습니다. 아래 스크립트에서 grep to array 라인을 살펴보세요. 도망쳐도 소용없을 것 같습니다. 하지만 정적으로 할당된 배열을 만들면 괜찮습니다.

예를 들어:

files=(somefile.txt
some\ other\ file.pdf
"yet another file.txt")

이것은 작동하지 않습니다:

#!/bin/bash
find . -name "$1" |
(
        cat - > /tmp/names
        file -N --mime-type --files-from /tmp/names
) |
(
        cat - > /tmp/mimes
#       files=("$(grep -o '^[^:]*' /tmp/mimes)") #one element array
#       files=($(grep -o '^[^:]*' /tmp/mimes)) #files with spaces end up split in to several elements
#       files=($(grep -o '^[^:]*' /tmp/mimes | sed 's/ /\\ /g')) #same but with \ terminated strings
        files=($(grep -o '^[^:]*' /tmp/mimes | cat <(echo '"') - <(echo '"')))
        mimes=($(grep -o '[^:]*$' /tmp/mimes))

        total=${#files[*]}
        for (( i=0; i<=$(( $total -1 )); i++ ))
                do
                echo Mime: "${mimes[$i]}" File: "${files[$i]}"
        done
        printf "$i\n"
)

편집하다: 설명

/tmp/mimes 파일에는 다음이 포함됩니다.

./New Text.txt: text/plain

":" 이전의 모든 것을 얻기 위해 grep하면

grep -o '^[^:]*' /tmp/mimes

출력: ./New Text.txt

이 출력을 배열에 넣고 싶지만 공백이 있으므로 sed를 사용하여 공백을 탈출합니다.

files=($(grep -o '^[^:]*' /tmp/mimes | sed 's/ /\\ /g'))

이것은 작동하지 않습니다. 나는 files[0] = "./New\" 및 files[1] = "Text.txt"로 끝납니다.

내 질문은 탈출 공간이 작동하지 않는 이유입니다.

만약 내가한다면:

files=(./New\ Text.txt)

작동하지만 왜 files[0] = "./New Text.txt" 이스케이프를 수동으로 수행할 때 작동하지만 grep 및 sed의 출력일 때는 작동하지 않습니다. 배열을 만드는 동작이 일관성이 없는 것 같습니다.

답변1

줄바꿈으로 구분된 파일 이름을 원할 경우 IFS를 다음으로 설정 $'\n'하고 글로빙을 끄십시오.

set -f
IFS=$'\n' files=($(grep -o '^[^:]*' /tmp/mimes))
set +f

파일 이름에 줄 바꿈(이름을 추출하기 위해 grep을 사용한 방식으로 인해 손상된 콜론 외에도)이 포함되어 있으면 중단될 것입니다.

관련 정보