在 bash 中使 if 语句不区分大小写

Make the if statement case insensitive in bash

我的代码将使用 curl 检查 headers。有时 headers 及其值以大写字母显示,有时以小写字母显示。

例如 X-Requested-Id 可以像 x-requested-idX-Requested-ID 那样找到。

如何使 if 语句不区分大小写?

if [[ $check_headers == "X-Requested-Id"* ]]; then

使用 Bash 4 或更新版本,您可以使用 parameter expansion 将字符串小写:

if [[ ${check_headers,,} == "x-requested-id"* ]]; then

如果您无权访问 Bash 4(或更新版本),您可以将单独的变量定义为小写,然后根据需要引用 'lowercase' 变量,例如:

$ myvar='ABC_def'
$ typeset -l myvar_lower="${myvar}"
$ echo "${myvar_lower}"
abc_def

返回 OP 问题:

typeset -l check_headers_lower="${check_headers}"

if [[ "${check_headers_lower}" == "X-Requested-Id"* ]]; then

备注:

  • 没有什么可以阻止您将原始变量定义为小写字母,只要您确定不会对原始大小写的数据提出后续要求
  • 改变变量的大小写不会影响变量的当前值; a) x=A; typeset -l x; echo "${x}" => A b) typeset -l x; x=A; echo "${x}" => a c) typeset -l x=A; echo "${x}" => a d) x=A; typeset -l x="${x}"; echo "${x}" => a

我更喜欢这里已经提出的所有其他建议,但是...

If,在紧要关头,您不记得那些语法,并且出于某种原因没有时间查找它们,请记住如果只是检查 return 它的操作数的值,所以你总是可以使用另一个程序。 (糟糕,我讨厌 运行 不必要的流程,但正如我所说,记住它是一种技巧...)

if grep -i x-requested-id <<< "$check_headers" # grep -i is case-insensitive

编辑

要详细说明 Benjamin 的解决方案(我认为它非常好),请尝试以下操作:

$: [[ X == x ]] && echo ok || echo no # case sensitive, fails
no
$: ( shopt -s nocasematch; [[ X == x ]] && echo ok || echo no; ) # in a subshell
ok
$: [[ X == x ]] && echo ok || echo no # back to normal
no

将其包装在子外壳中会限制 nocasematch 的范围。

你说他的解决方案“行不通”。能详细点吗?

使用 nocasematch shell 选项。就像评论中提到的 Gordon Davisson 一样,应该在测试后禁用它并提防其他模式匹配,例如使用 =~ 运算符。

shopt -s nocasematch
if [[ $check_headers == "X-Requested-Id"* ]]; then
 ...
fi
shopt -u nocasematch

就像@Benjamin W. 在评论中提到的那样,最好先检查值 shopt.

的状态

使用eval

oldvalue=$(shopt -p nocasematch)
shopt -s nocasematch

if [[ $check_headers == "X-Requested-Id"* ]]; then
     ...
fi

eval "$oldvalue"

我会先检查 shopt 的状态再启用它,然后再禁用它。

没有 eval,像这样

#!/usr/bin/env bash

if ! shopt -q nocasematch; then
  shopt -s nocasematch
  on=1
fi

if [[ $check_headers == "X-Requested-Id"* ]]; then
  ....
fi

if ((on)); then 
  shopt -u nocasematch
  on=0
fi