명령을 입력할 때 이스케이프 공백을 "ls"와 함께 사용할 수 없습니다.

명령을 입력할 때 이스케이프 공백을 "ls"와 함께 사용할 수 없습니다.

처음 가보는 곳인데 혹시 놓친 부분이 있다면 죄송합니다.

저는 현재 모든 폴더를 검색하고 작업을 수행 <filename>.vmdk할 파일을 찾는 스크립트를 작성 중입니다 .ls -lah

이것은 내 현재 스크립트 코드입니다.

#!/bin/bash

parse_dir () {
    for file in ./**/*[A-Za-z][!-flat][!-thin].vmdk; do
    #echo "File Found: "${file//\ /\\\ }
    ls -lah "${file//\ /\\\ }"
    #vmkfstools -i "${file//\ /\\\ }" -d thin "${file%.vmdk}-thin.vmdk"
    #echo "New provisioned file: ${file%.vmdk}-thin.vmdk"
    done
}

parse_dir

스크립트는 일치하는 모든 파일을 다음과 같이 출력합니다. ls: ./ABC\ Collector/ABC\ Collector.vmdk: No such file or directory

하지만! ls -lah ./ABC\ Collector/ABC\ Collector.vmdk이 파일이 존재한다고 수동으로 입력하면 괜찮을 것입니다.

여기서 뭔가 빠졌나요?

답변1

공백이 인용 확장의 결과인 경우 이를 이스케이프할 필요가 없습니다.

$ touch 'some file.txt'
$ ls -l some\ file.txt 
-rw-r--r-- 1 ilkkachu ilkkachu 0 Sep 17 01:03 some file.txt
$ f='some file.txt'
$ ls -l "$f"
-rw-r--r-- 1 ilkkachu ilkkachu 0 Sep 17 01:03 some file.txt

실제로 보시다시피 작동하지 않습니다. 따옴표와 이스케이프는 변수 확장 이전에만 특별하며 확장 결과로 생성된 따옴표는 아닙니다. 셸 명령줄에서 변수를 확장하는 것은 단순히 명령줄의 동일한 위치에 변수 내용을 문자 그대로 배치하는 것과 다릅니다. (매크로 프로세서가 아니라 프로그래밍 언어입니다.)

$ s='foo\ bar'
$ printf ':%s\n' $s
:foo\
:bar
$ printf ':%s\n' "$s"
:foo\ bar

따옴표가 없으면 값은 s공백(내용 기준 IFS)으로 분할되지만 따옴표가 있으면 그렇지 않습니다. 두 경우 모두 백슬래시는 공백을 벗어나지 않습니다.

이와 같은 for 루프에서는 다음을 수행할 수 있습니다.

for f in ./**/*.vmdk; do
    ls -l "$f"
done

이것이 *[A-Za-z][!-flat][!-thin].vmdk의미하는 바가 아닐 수도 있지만 [A-Za-z]하나의 알파벳 문자와 일치하고 [!-flat]모든 문자와 일치합니다.하나-, f, l또는 의 문자 a가 아닙니다 t. 예를 들어, 여기에는 가 포함되지만 abc.vmdk는 포함되지 않습니다 bac.vmdk.

대신, 다른 조건을 사용하여 원치 않는 사례를 제외하세요.

for file in ./**/*.vmdk; do
    case "$file" in
        *-flat.vmdk) continue;;
        *-thin.vmdk) continue;;
    esac
    echo "found: $file"
    ls -l "$file"
    new=${file%.vmdk}-thin.vmdk
    # vmkfstools -i "$file" -d thin "$new"
    # echo "New provisioned file: $new"
done

바라보다:

답변2

파일 이름의 공백은 당신을 싫어할 것이고 당신도 싫어할 것입니다. 특히 파일 이름에서 스크립트 쉘 명령에 와일드카드로 공백을 전달할 때 더욱 그렇습니다. find우리가 xargs당신을 위해 힘든 일을 해 드리겠습니다 :

$  tree
.
+--- ABC Collector
|   +--- ABC Collector-flat.vmdk
|   +--- ABC Collector-thin.vmdk
|   +--- ABC Collector.vmdk
$  find . -type f -name '*.vmdk' -not -name '*-flat.vmdk' -not -name '*-thin.vmdk' -print0 | xargs -0 ls -lah
-rw-r--r--    1 myuser mygroup       0 Sep 16 14:29 ./ABC Collector/ABC Collector.vmdk

관련 정보