我在Linux上使用bash。我从以下if语句中获得了成功,但是这不应该返回失败代码吗?
if [[ ■ = [⅕⅖⅗] ]] ; then echo yes ; fi
正方形不等于任何字符,所以我看不到为什么我得到一个成功代码。
对于我来说,保持双括号很重要。
在这种情况下,还有其他方法可以做一个范围吗,或者还有什么其他建议?
C
这里不是单字节字符,所以不会在这里做。C.UTF-8
将在可用的地方做。
我在Linux上使用bash。我从以下if语句中获得了成功,但是这不应该返回失败代码吗?
if [[ ■ = [⅕⅖⅗] ]] ; then echo yes ; fi
正方形不等于任何字符,所以我看不到为什么我得到一个成功代码。
对于我来说,保持双括号很重要。
在这种情况下,还有其他方法可以做一个范围吗,或者还有什么其他建议?
C
这里不是单字节字符,所以不会在这里做。C.UTF-8
将在可用的地方做。
Answers:
这是那些字符具有相同排序顺序的结果。
您还会注意到
sort -u << EOF
■
⅕
⅖
⅗
EOF
仅返回一行。
或者那个:
expr ■ = ⅕
返回true(根据POSIX的要求)。
GNU系统附带的大多数语言环境都有许多具有相同排序顺序的字符(甚至字符序列(整理序列))。对于那些■⅕⅖⅗字符,是因为未定义顺序,而未定义顺序的那些字符最终在GNU系统中具有相同的排序顺序。有些字符被明确定义为具有相同的排序顺序,例如Ș和Ş(尽管对我而言,显然(无论如何)没有真正的逻辑或一致性)。
这就是令人惊讶和虚假行为的根源。我最近在Austin组(POSIX和Single UNIX Specification背后的机构)邮件列表中提出了这个问题,并且直到2015-04-03讨论仍在进行中。
在这种情况下,我不清楚是否[y]
应该x
在何处进行匹配x
以及y
在何处进行排序,但是我不清楚,但是由于方括号表示要与归类元素进行匹配,因此这表明了bash
预期的行为。
无论如何,我想[⅕-⅕]
还是至少[⅕-⅖]
应该匹配■
。
您会注意到,不同的工具的行为有所不同。ksh93的行为类似于bash
,GNU grep
或sed
不。其他一些外壳具有不同的行为,例如yash
更多的越野车。
为了具有一致的行为,您需要一个所有字符排序不同的语言环境。C语言环境是典型的语言环境。但是,在大多数系统上,C语言环境中的字符集是ASCII。在GNU系统上,您通常可以访问一个C.UTF-8
语言环境,而该语言环境可用于处理UTF-8字符。
所以:
(export LC_ALL=C.UTF-8; [[ ■ = [⅕⅖⅗] ]])
或等效的标准:
(export LC_ALL=C.UTF-8
case ■ in ([⅕⅖⅗]) true;; (*) false; esac)
应该返回false。
另一种选择是仅LC_COLLATE
将C 设置为可在GNU系统上使用,但不必在可能无法指定多字节字符的排序顺序的其他系统上设置。
其中一个教训是,在比较字符串时,相等性并不像人们期望的那样清晰。平等可能意味着从最严格到最不严格。
现在,对于2或3,假定两个字符串都包含有效字符。在UTF-8和其他一些编码中,某些字节序列不能形成有效字符。
因此,图1和图2不一定相等,或者因为某些字符可能具有不止一种可能的编码。这通常是有状态编码(例如ISO-2022-JP)的情况,其中A
可以表示为41
或1b 28 42 41
(1b 28 42
是切换为ASCII的序列,您可以根据需要插入任意数量的序列,这不会造成任何影响),尽管我不会指望这些编码类型仍在使用,并且GNU工具至少通常不能正常使用它们。
还要注意,大多数非GNU实用程序不能处理0字节值(ASCII中的NUL字符)。
使用哪个定义取决于实用程序以及实用程序的实现或版本。POSIX还不是100%清楚。在C语言环境中,所有3个都是等效的。在那个YMMV之外。
é
并é
使用相同的字符串,但不要使用相同的字符串e
。POSIX的排序顺序概念很少是正确的,它过于依赖于字符,并且不能解释大多数常见的字符串排序方式(例如,法语词典不使用字典顺序来对单词进行排序:他们进行了首个字典顺序,忽略了重音,然后使用重音来确定联系)。
您做错了,=
并且==
不一样。
尝试以下示例:
if [[ "■" == "[⅕⅖⅗]" ]] ; then echo yes ; else echo no ; fi
if [[ "1" == "1" ]] ; then echo yes ; else echo no ; fi
if [[ "■" == "■" ]] ; then echo yes ; else echo no ; fi
=
应使用运算符检查相等性。问题是缺少引号,而不是运算符。
man bash
在该[[
节中也要说:“ =运算符等于==。”
[[...]]
运算符。和=和==在shell中实现相同(ksh / bash / zsh)并且用于模式匹配,而不是相等。