简化 bash 条件的序列

简化 bash 条件的序列

我有这些 bash 命令序列,想简化它。任何帮助,将不胜感激。

  [[ "$fl" == *"img"* ]] && mv "$flimg" "$out"
  [[ "$fl" == *"png"* ]] && mv "$flimg" "$out"
  [[ "$fl" == *"jpg"* ]] && mv "$flimg" "$out"
  [[ "$fl" == *"tif"* ]] && mv "$flimg" "$out"

答案1

bash 支持扩展正则表达式,您可以在其中执行所有检查,例如:

[[ $file =~ (img|png|jpg|tif) ]] && echo do-something

检查变量是否文件包含任何给定的字符串(请注意,我使用=~操作员用于正则表达式匹配)。

答案2

作为正则表达式的替代方案,一种不太优雅的方法是组合条件句通过使用OR- 在 Bash 中是双管道 ( ||):

[[ "$fl" == *"img"* || "$fl" == *"png"* || "$fl" == *"jpg"* || "$fl" == *"tif"* ]] && mv "$flimg" "$out"

双管道也可以在 Bourne 或 Korn shell 中工作 - 仅使用单大括号 ( []) 并更改===(仅适用于 Bourne),例如

[ "$fl" = *"img"* || "$fl" = *"png"* || "$fl" = *"jpg"* || "$fl" = *"tif"* ] && mv "$flimg" "$out"

答案3

使用 POSIX 标准sh语法(在 中也有效)bash,您可以case在此处使用语句:

case $fl in
    *img*|*jpg*|*png*|*tif*)
        mv -- "$flimg" "$out"
esac

或者,作为“一行”,

case $fl in (*img*|*jpg*|*png*|*tif*) mv -- "$flimg" "$out"; esac

如果您使用 启用extglobshell 选项shopt -s extglob,您还可以使用

[[ $fl == *@(img|jpg|png|tif)* ]] && mv -- "$flimg" "$out"

如果您只想测试文件名中最后一个点之后的文件名后缀$fl

case ${fl##*.} in (img|jpg|png|tif) mv -- "$flimg" "$out"; esac

或者,之后shopt -s extglob

[[ ${fl##*.} == @(img|jpg|png|tif) ]] && mv -- "$flimg" "$out"

标准扩展从匹配${variable##pattern}中删除最长的前缀字符串。使用as 模式意味着删除值中直到并包括最后一个点的所有内容。$variablepattern*.

请注意,此答案中完成的所有模式匹配都是通过 shell 模式而不是正则表达式进行的。

相关内容