使用“for file in”选择多个扩展名,然后获取“file”的基本名称,然后连接扩展名

使用“for file in”选择多个扩展名,然后获取“file”的基本名称,然后连接扩展名

我正在尝试练习我的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

相关内容