在 bash 中使 if 语句不区分大小写
Make the if statement case insensitive in bash
我的代码将使用 curl 检查 headers。有时 headers 及其值以大写字母显示,有时以小写字母显示。
例如 X-Requested-Id
可以像 x-requested-id
或 X-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
我的代码将使用 curl 检查 headers。有时 headers 及其值以大写字母显示,有时以小写字母显示。
例如 X-Requested-Id
可以像 x-requested-id
或 X-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