初めて行ってみるところですが、もし逃した部分があると申し訳ありません。
私は現在、すべてのフォルダを検索し、作業を実行する<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
望むより: