for file in *.jpg;
Unixのスキルを練習しようとしています。私は作業ディレクトリ内のすべてのファイルを選択する方法を学びましたが、ここで.jpg
停止したくありません。 bashスクリプトを2回実行したくありません。
シナリオは次のとおりです。このファイルが与えられ、各ファイルを選択して拡張子を別のファイルに置き換えたいと思います。プロセスがbasename
+ ".done"に等しいことを望みます。test1.jpg
test1.done
test1.jpg
test2.jpeg
test3.txt
test4.dummy
今私が望むのは、何らかの方法でこれらの拡張を.jpg,.jpeg,.txt,.dummy
配列に配置してから、for
このようなループで使用することですfor file in *{.jpg,.jpeg,.txt,.dummy}; do
。しかし、試してみましたが、うまくいきません。シェルがforループでこれを許可していないようです。ソート?
誰かが私を助けて、この問題を解決する方法の例を教えてください。ありがとうございます!
修正する
だから私はfor file in *.{jpg,jpeg,test}
私が問題を解決できることを学びました。しかし、時には失敗します。特に、拡張子が宣言された配列にファイルがない場合は、さらにそうです。
例:
test1.jpg
test2.jpeg
test3.test
test4.dummy
次のようにbashを使用します。
for file in *.{jpg,jpeg,test,avi}; do size=$(stat -c '%s' "$file"); echo $file filesize is: $size; done
やっぱり醜くなるだろうな
test1.jpg filesize is: 2
test2.jpeg filesize is: 0
test3.test filesize is: 0
stat: cannot stat `*.avi': No such file or directory
*.avi filesize is:
上記の最後の2行は不要です。このようなものがあればいいのに、何も見つからない場合はbreak
やめてください。for
avi
do
可能ですか?
答え1
以下を使用してオプションをbash
設定できますnullglob
。
nullglob
If set, bash allows patterns which match no files (see
Pathname Expansion above) to expand to a null string,
rather than themselves.
表示するには:
$ ls
test1.dummy test1.jpeg test1.jpg test1.test
$ shopt nullglob
nullglob off
$ for file in *.{jpg,jpeg,test,avi}; do
echo "$file size is $(stat -c '%s' "$file")";
done
test1.jpg size is 0
test1.jpeg size is 0
test1.test size is 0
stat: cannot stat ‘*.avi’: No such file or directory
*.avi size is
有効にするとnullglob
:
$ shopt -s nullglob
$ shopt nullglob ## just to demonstrate that it is on
nullglob on
$ for file in *.{jpg,jpeg,test,avi}; do
echo "$file size is $(stat -c '%s' "$file")"
done
test1.jpg size is 0
test1.jpeg size is 0
test1.test size is 0
または、ファイルが存在することを確認できます。 (また、ここでは中括弧の拡張が不要であることを示すために、上部にあるこの例を使用しました。)
$ for file in *jpg *jpeg *test *avi; do
[ -e "$file" ] && echo "$file size is $(stat -c '%s' "$file")"
done
test1.jpg size is 0
test1.jpeg size is 0
test1.test size is 0