当nocasematch关闭时,为什么case语句区分大小写?

Tod*_*obs 6 bash pattern-matching

鉴于以下内容:

$ echo $BASH_VERSION
4.2.10(1)-release

$ shopt | fgrep case
nocaseglob      off
nocasematch     off

$ case A in [a-z]) echo TRUE;; esac
TRUE
Run Code Online (Sandbox Code Playgroud)

我想到的是,大写字母一个应该匹配小写字符类[AZ] ,但它确实.为什么这场比赛没有失败?

Ray*_*oal 7

您不能以这种方式可靠地使用破折号.如果我不使用短划线,它按预期工作:

$ bash --version
GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ shopt -s nocasematch
$ case A in [abc]) echo TRUE;; esac
TRUE
$ shopt -u nocasematch
$ case A in [abc]) echo TRUE;; esac
$ 
Run Code Online (Sandbox Code Playgroud)

但是使用破折号,无论设置如何,它都会打印为TRUE nocasematch.

Bash在这里进行模式匹配.查看参考手册的这一部分,其中使用连字符MIGHT解释[a-z][A-Za-z]!它告诉您如何获得传统解释(将LC_COLLATE或LC_ALL设置为C).基本上,您的默认语言环境是按字典顺序排序.参考手册很好地解释了事情.

附录

好的,我有一份成绩单给你.

$ shopt -u nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
$ shopt -s nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
$ LC_ALL=C
$ shopt -u nocasematch
$ case A in [a-z]) echo TRUE;; esac
$ shopt -s nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
Run Code Online (Sandbox Code Playgroud)


pax*_*blo 7

它与您的区域设置有关.具体而言,整理顺序是不区分大小写的顺序.

例如,LC_COLLATE设置为en_AU.utf8(我的系统上的默认值),您可以看到它包含小写和大写:

pax> case A in [a-b]) echo TRUE;; esac
TRUE
pax> _
Run Code Online (Sandbox Code Playgroud)

但是,如果你摆脱范围说明符,它按预期工作:

pax> case A in [ab]) echo TRUE;; esac
pax> _
Run Code Online (Sandbox Code Playgroud)

那是因为第一种方法between a and b inclusive,对于整理顺序,包括A.对于后者而言a,b仅仅是,不是受整理顺序影响的范围.

如果将整理顺序设置为区分大小写的顺序,则它可以按预期工作:

pax> export LC_COLLATE="C"
pax> case A in [a-b]) echo TRUE;; esac
pax> 
Run Code Online (Sandbox Code Playgroud)

如果您只想将其作为一次性操作而不影响其他任何操作,则可以在子shell中执行此操作:

( export LC_COLLATE="C" ; case A in [a-b]) echo TRUE;; esac )
Run Code Online (Sandbox Code Playgroud)