我有这些 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
如果您使用 启用extglob
shell 选项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 模式意味着删除值中直到并包括最后一个点的所有内容。$variable
pattern
*.
请注意,此答案中完成的所有模式匹配都是通过 shell 模式而不是正则表达式进行的。