Как сравнить строки в Bash

675

Как сравнить переменную с строкой (и сделать что-то, если они совпадают)?

Теги:
string

10 ответов

1039
Лучший ответ

Попробуй это:

if [ "$x" = "valid" ]; then
  echo "x has the value 'valid'"
fi

Если вы хотите что-то сделать, когда они не совпадают, замените = с !=. Вам нужны кавычки вокруг $x, потому что если $x пуст, вы получите if [ = "valid" ]... который является синтаксической ошибкой.


Обратите внимание, что bash позволяет использовать == с [, но это не стандартно. Либо используйте [[ "$x" == "valid" ]] (в этом случае котировки вокруг $x являются необязательными) или [ "$x" = "valid" ].

  • 11
    Как это связано с принятым ответом, данным в « Неожиданная ошибка оператора» ? Я получил ту же ошибку при использовании [ "$1" == "on" ] . Изменение этого значения на ["$ 1" = "on"] решило проблему.
  • 8
    это не должно быть ["x$yes" == "xyes"] в коде?
Показать ещё 22 комментария
110

Или, если вам не нужно предложение else:

[ "$x" == "valid" ] && echo "x has the value 'valid'"
  • 64
    И если вам действительно нужно предложение else и вы хотите создать сумасшедший однострочный текст: ["$ x" == "valid"] && echo "valid" || эхо "неверно"
  • 9
    @MattWhite: обычно это плохая идея, так как echo может потерпеть неудачу.
Показать ещё 5 комментариев
56

Для сравнения строк с подстановочными знаками используйте

if [[ "$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do Something here
fi
  • 11
    Важно, чтобы подстановочные знаки можно было использовать только с правой стороны! Также обратите внимание на отсутствие " вокруг символов подстановки. (Кстати: +1 для символов подстановки!)
  • 5
    Расширение $stringB должно быть $stringB кавычки (и, кстати, левая сторона не должна заключаться в кавычки): if [[ $stringA = *"$stringB"* ]]; then .
Показать ещё 1 комментарий
42
a="abc"
b="def"

# Equality Comparison
if [ "$a" == "$b" ]; then
    echo "Strings match"
else
    echo "Strings don't match"
fi

# Lexicographic (greater than, less than) comparison.
if [ "$a" \< "$b" ]; then
    echo "$a is lexicographically smaller then $b"
elif [ "$a" \> "$b" ]; then
    echo "$b is lexicographically smaller than $a"
else
    echo "Strings are equal"
fi

Примечания:

  • Пространства между if и [ и ] важны
  • > и < являются операторами перенаправления, поэтому избегайте их с помощью \> и \< соответственно для строк.
  • 4
    Спасибо за сравнение строки в алфавитном порядке
  • 0
    Мой вопрос заключается в том , что $a на самом деле были " " вокруг него как часть строки буквального значения, поэтому я должен был использовать символ перехода к $b для сравнения значений. Я смог найти это после запуска bash -x ./script.sh , флаг -x позволяет увидеть значение каждого выполнения и помогает в отладке.
Показать ещё 1 комментарий
23

Я должен не согласиться с одним из комментариев в одном пункте:

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

Нет, это не сумасшедший oneliner

Это просто похоже на одного, хм, непосвященного...

Он использует общие шаблоны как язык, в некотором роде;

И после того, как вы выучили язык.

На самом деле, приятно читать

Это простое логическое выражение с одной специальной частью: ленивая оценка логических операторов.

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

Каждая часть является логическим выражением; первое может быть истинным или ложным, остальные два всегда верны.

(
[ "$x" == "valid" ] 
&&
echo "valid"
)
||
echo "invalid"

Теперь, когда он оценивается, проверяется первое. Если это ложь, то второй операнд логики и && после него не имеет значения. Во-первых, это неверно, поэтому в любом случае это не может быть первым и вторым.
Теперь в этом случае первая сторона логики или || false, но это может быть правдой, если другая сторона - третья часть - истинна.

Таким образом, третья часть будет оценена - в основном, запись сообщения в качестве побочного эффекта. (Он имеет результат 0 для истины, который мы здесь не используем)

Другие случаи похожи, но проще - и - я обещаю! - может быть - легко читать!
(У меня его нет, но я думаю, что стать ветераном UNIX с седой бородой очень помогает.)

  • 13
    ... && ... || ... обычно хмурится (извините, седобородый ветеран Unix, вы все время ошибались), так как это семантически не эквивалентно if ... then ... else ... Не волнуйтесь, это распространенная ошибка .
  • 6
    @gniourf_gniourf OP не ошибается - и они, вероятно, не знают, как вы предлагаете. ... && ... || ... это совершенно правильный шаблон и распространенная идиома bash. Его использование действительно предписывает предварительные знания (что может быть полезно иметь в виду, если в аудитории есть новички), но у ОП есть шанс доказать, что они знают, как избегать открытых крышек люков.
Показать ещё 4 комментария
19

вы также можете использовать прецедент /esac

case "$string" in
 "$pattern" ) echo "found";;
esac
  • 0
    Это эквивалентность или содержит?
10

после script читается из файла с именем "testonthis" по строке, а затем сравнивает каждую строку с простой строкой, строкой со специальными символами и регулярным выражением, если она не соответствует, тогда script будет печатать строку o/w не.

пространство в bash так важно. поэтому последующие будут работать

[ "$LINE" != "table_name" ] 

но следующее не будет:

["$LINE" != "table_name"] 

поэтому, пожалуйста, используйте как есть:

cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done
  • 0
    Используйте этот подход для просмотра файла. То есть удалите UUoC среди прочего.
8

Я бы, вероятно, использовал совпадения регулярных выражений, если на входе было всего несколько действительных записей. Например. действительными действиями являются только "старт" и "остановка".

if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
  echo "valid action"
fi

Обратите внимание, что я строчу переменную $ACTION с помощью двойной запятой. Также обратите внимание, что это не будет работать на слишком старых версиях bash.

3

Bash4+. Примечание: не использовать кавычки вызовет проблемы, когда слова содержат пробелы и т.д. Всегда указывайте в bash IMO.

Вот несколько примеров Bash4+:

Пример 1, проверьте "да" в строке (без учета регистра):

    if [[ "${str,,}" == *"yes"* ]] ;then

Пример 2, проверьте "да" в строке (без учета регистра):

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

Пример 3, проверьте "да" в строке (с учетом регистра):

     if [[ "${str}" == *"yes"* ]] ;then

Пример 4, проверьте "да" в строке (с учетом регистра):

     if [[ "${str}" =~ "yes" ]] ;then

Пример 5, точное совпадение (с учетом регистра):

     if [[ "${str}" == "yes" ]] ;then

Пример 6, точное совпадение (без учета регистра):

     if [[ "${str,,}" == "yes" ]] ;then

Пример 7: точное совпадение:

     if [ "$a" = "$b" ] ;then

наслаждаться.

1

Я сделал это таким образом, который совместим с bash, dash (sh):

testOutput="my test"
pattern="my"

case $testOutput in (*"$pattern"*)
    echo "if there is a match"
    exit 1
    ;;
(*)
   ! echo there is no coincidence!
;;esac

Ещё вопросы

Сообщество Overcoder
Наверх
Меню