我正在尝试练习我的unix技能,我刚刚学会了如何使用for file in *.jpg;
它的作用是选择.jpg
工作目录中的所有文件,但我不想就此停止,我不想运行我的bash脚本两次
所以这是场景,我得到了这些文件,我希望选择其中的每一个,然后将扩展名替换为另一个,我希望该过程类似于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
,但我尝试了它,但它不起作用,shell似乎不允许在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:
上面的最后两行是不必要的,我希望有类似的东西,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