如何在Bash中测试字典小于或等于的字典?

How to test strings for lexicographic less than or equal in Bash?

在bash中,是否有一种简单的方法来测试一个字符串在词典上是否小于或等于另一个字符串?

我知道你能做到:

1
if [["a" <"b" ]]

用于检验严格不等式,或

1
if [[ 1 -le 1 ]]

对于数字。但-le似乎不适用于字符串,使用<=会产生语法错误。


只需否定大于测试:

1
if [[ !"a">"b" ]]

您需要在附加条件下使用||,而不是使用<=

1
[["$a" <"$b" ||"$a" =="$b" ]]


您可以翻转比较并签名,然后进行负面测试:

1
2
3
4
$ a="abc"
$ b="abc"
$ if ! [["$b">"$a" ]] ; then  echo"a <= b" ; fi
a <= b

如果你想整理"A"的序列,然后是"A"然后是"B"…用途:

1
shopt -s nocaseglob

exprposix方法

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expr.html

1
2
["$(expr abc \< acb)" = 1 ] || echo fail
["$(expr abc \< aac)" = 0 ] || echo fail

posix说expr决定参数是整数还是普通字符串,如果字符串比较:

returns the result of a string comparison using the locale-specific collation sequence

sortposix解决方案

为了好玩,用expr代替。

对于使用换行符的字符串不是无限健壮的,但是在处理shell脚本时,它是什么时候?

1
2
3
4
5
6
7
8
9
10
11
12
string_lte() (
  s="$(printf"${1}
${2}")"
  if ["$(printf"$s" | sort)" ="$s" ]; then
    exit 0
  else
    exit 1
  fi
)
string_lte abc adc || echo fail
string_lte adc adc || echo fail
string_lte afc adc && echo fail

如果您可以使用bash语法,请参阅@anubhava和@gordon davison的答案。对于POSIX语法,您有两个选项(注意必要的反斜杠!):

使用-o运算符(或):

1
["$a" \<"$b" -o"$a" ="$b" ] && echo"'$a' LTE '$b'" || echo"'$a' GT '$b'"

或使用否定:

1
[ !"$a" \>"$b" ] && echo"'$a' LTE '$b'" || echo"'$a' GT '$b'"

我更喜欢第一种变体,因为imho更容易阅读。