Как проверить строки на лексикографию, меньшую или равную в Bash?
В Bash, есть ли простой способ проверить, является ли одна строка лексикографически меньше или равна другой?
Я знаю, что вы можете сделать:
if [[ "a" < "b" ]]
для проверки строгого неравенства, или
if [[ 1 -le 1 ]]
для номеров. Но -le
не похоже на работу со строками, а использование <=
дает синтаксическую ошибку.
5 ответов
Вам нужно использовать ||
with an additional condition instead of <=
:
[[ "$a" < "$b" || "$a" == "$b" ]]
sort
POSIX обходной путь
Не бесконечно устойчивы к строкам с символами новой строки, но когда это когда-либо происходит при работе со скриптами оболочки?
string_lte() (
s="$(printf "${1}\n${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
Вы можете перевернуть сравнение, подписать и проверить отрицательно:
$ a="abc"
$ b="abc"
$ if ! [[ "$b" > "$a" ]] ; then echo "a <= b" ; fi
a <= b
Если вы хотите упорядочить последовательность "A", затем "a", затем "B"... используйте:
shopt -s nocaseglob
Если вы можете использовать синтаксис Bash, посмотрите ответы @anubhava и @gordon-davisson. С синтаксисом POSIX у вас есть две опции (обратите внимание на необходимые обратные слеши!):
с использованием -o
оператор (ИЛИ):
[ "$a" \< "$b" -o "$a" = "$b" ] && echo "'$a' LTE '$b'" || echo "'$a' GT '$b'"
или используя отрицание:
[ ! "$a" \> "$b" ] && echo "'$a' LTE '$b'" || echo "'$a' GT '$b'"
Я предпочитаю первый вариант, потому что imho он более читабелен.