改善周期的执行

时间:2014-12-05 14:16:37

标签: bash glob

我已经完成了一个小批量脚本来调整(飞行)一些图像:

for a in *.{png,PNG,jpg,JPG,jpeg,JPEG,bmp,BMP} ;
do convert "$a" -resize $re "$re""_tmp/${a%.*} ["$re"].jpg" ; done

它运行。

问题:如果在目录内只有(一个实例) .png 文件,脚本会运行,但会显示一些错误,因为没有其他文件扩展名( PNG ,JPG,JPG,JPEG,JPEG,BMP,BMP

改善它的最佳方法是什么?将stderr重定向到/dev/null?任何的想法?我想检查($?)脚本的退出状态,添加if / then以显示脚本是否正确运行。

2 个答案:

答案 0 :(得分:4)

两个简单的解决方案。

使用shopt builtinnullglob选项,以便不匹配的全局消失而不是保留文字。

$ ls *.foo
ls: *.foo: No such file or directory
$ echo one *.foo two
one *.foo two
$ shopt -s nullglob
$ echo one *.foo two
one two

所以你的脚本会变成。

shopt -s nullglob
for a in *.{png,PNG,jpg,JPG,jpeg,JPEG,bmp,BMP} ;
do convert "$a" -resize $re "$re""_tmp/${a%.*} ["$re"].jpg" ; done

或者在使用convert之前测试文件是否存在。

for a in *.{png,PNG,jpg,JPG,jpeg,JPEG,bmp,BMP} ;
do [ -f "$a" ] && convert "$a" -resize $re "$re""_tmp/${a%.*} ["$re"].jpg" || :; done

答案 1 :(得分:1)

我想澄清为什么你的脚本没有像你期望的那样工作,以及为了以防再添加另一种可能性。

为什么会看到错误?

这是制作for循环的一般方法:

for name [ [ in [ word ... ] ] ; ] do list ; done

在您的代码中,word*.{png,PNG,jpg,JPG,jpeg,JPEG,bmp,BMP},假设您只有 .png 文件,则会扩展如下:

  • Brace Expansion

    *.png *.PNG *.jpg *.JPG *.jpeg *.JPEG *.bmp *.BMP
    
  • Filename Expansion

    file1.png file2.png *.PNG *.jpg *.JPG *.jpeg *.JPEG *.bmp *.BMP
    
  • 示例

    $ ls
    file1.png  file2.png
    $ echo *.{png,PNG,jpg,JPG,jpeg,JPEG,bmp,BMP}
    file1.png file2.png *.PNG *.jpg *.JPG *.jpeg *.JPEG *.bmp *.BMP
    

在此步骤中,这些是您将逐个分配给变量name的字符串。
例如:$name -> *.JPG


使用The Shopt Builtin

改善扩展

作为第一个建议,您可以使用nocaseglob

  

如果设置,Bash在执行文件名扩展时会以不区分大小写的方式匹配文件名。

使用此选项,您可以将word缩减为*.{png,jpg,jpeg,bmp}

  • 示例

    $ shopt -s nocaseglob
    $ echo *.{png,jpg,jpeg,bmp}
    file1.png file2.png *.jpg *.jpeg *.bmp
    

    甚至是*.{PNG,jpg,jpeg,bmp}

    $ echo *.{PNG,jpg,jpeg,bmp}
    file1.png file2.png *.jpg *.jpeg *.bmp
    

最后,正如@Etan建议的那样,您可以使用nullglob选项:

  

如果设置,Bash允许不匹配任何文件的文件名模式扩展为空字符串,而不是自己。

  • 示例

    $ shopt -s nullglob
    $ echo *.{png,jpg,jpeg,bmp}
    file1.png file2.png
    

在这种情况下,作为nullglob的替代方法,您可以使用extglob选项(默认情况下有时启用):

  

如果设置,则启用扩展模式匹配功能。

这些是extended pattern matching features

?(pattern-list)
    Matches zero or one occurrence of the given patterns.
*(pattern-list)
    Matches zero or more occurrences of the given patterns.
+(pattern-list)
    Matches one or more occurrences of the given patterns.
@(pattern-list)
    Matches one of the given patterns.
!(pattern-list)
    Matches anything except one of the given patterns.

因此,您可以将word写为*.*(png|jpg|jpeg|bmp)

  • 示例

    $ shopt -u nullglob
    $ shopt -s extglob
    $ echo *.+(png|jpg|jpeg|bmp)
    file1.png file2.png
    

通过这种方式,它在Filename Expansion步骤中全部展开。