파일 이름에 괄호가 포함되어 있으면 찾기가 실패합니다.

파일 이름에 괄호가 포함되어 있으면 찾기가 실패합니다.

파일 이름 + 원하는 문자열과 일치하는 파일이 포함된 변수를 생성하기 위해 루프 내에서 find를 사용하려고 합니다.

예:

file1.en.srt
file1.mkv
file1.pt.srt

코드의 관련 부분은 다음과 같습니다.

shopt -s nullglob
shopt -s nocaseglob

if [ -d "$1" ]; then
    for file in "${1%/}/"*mkv; do
        # Get filename to match against subs and audios
        filename="$(basename "$file" .mkv)"

        # Find matching subtitle file
        engsubs="$(find . -name "$filename*en.srt*" | sed -e 's,^\./,,')"   

        # Find matching audio file
        engaudio="$(find . -iname "$filename*en.ac3" -o -iname "$filename*en.eac3" -o -iname "$filename*en.dts" | sed -e 's,^\./,,')" 
    done
fi

파일에 괄호가 없으면 작동하지만 find이름에 괄호가 포함된 파일에 대해서는 명령이 아무것도 찾지 않습니다. 왜 이런 일이 발생합니까? 다음을 $en포함하는 이와 같은 변수를 만들고 싶습니다.file1.en.srt

답변1

문제는 전역 [문자 ]입니다. 예를 들어 다음 파일을 고려해보세요.

ba[r].mkv

이 파일에서 스크립트를 실행하면 $filename다음과 같습니다. ba[r]따라서 find명령은 다음과 같습니다.

find . -name 'ba[r]*pt-BR.srt*'

[r]이는 단일 문자 문자 클래스이므로 를 의미합니다 . 따라서 명령은 , 로 시작하는 파일 이름 , 임의의 문자, 다시 임의의 문자를 r찾습니다 . 대괄호를 이스케이프 처리해야 합니다.barpt-BR.srt

find . -name 'ba\[r\]*pt-BR.srt*'

가장 간단한 방법은 printf및 를 사용하는 것입니다 %q. 따라서 다음 줄을 변경하십시오.

filename="$(basename "$file" .mkv)"

이와 관련하여:

filename=$(printf '%q' "$(basename "$file" .mkv)")

또는 주변 명령 대체 없이 다음을 수행합니다 printf.

printf -v filename '%q' "$(basename "$file" .mkv)"

관련 정보