コマンドを入力すると、エスケープスペースを「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意味するものではないかもしれませんが、1つ[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

関連情報