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

问题描述

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

例如,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(或更新版本),您可以将单独的变量定义为小写,然后根据需要引用“小写”变量,例如:

$ 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 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 外壳选项。就像 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