11

В Bash как проверить, начинается ли строка с определённого значения?

14

Я хотел бы проверить, начинается ли строка с "node", например, "node001". Что-то вроде:

if [ $HOST == node* ]
then
  echo yes
fi

Как я могу сделать это правильно?


Кроме того, мне нужно объединить выражения, чтобы проверить, является ли переменная HOST либо "user1", либо начинается с "node":

if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi

> > > -bash: [: слишком много аргументов

Как я могу сделать это правильно?

5 ответ(ов)

2

Я всегда стараюсь придерживаться POSIX sh вместо использования расширений Bash, так как одной из основных целей сценарного программирования является портативность (кроме связывания программ, а не замены их).

В sh есть простой способ проверить условие "является префиксом".

case $HOST in node*)
    # Ваш код здесь
esac

С учетом того, насколько старым, архаичным и неуклюжим является sh (и Bash не является решением: он более сложен, менее последователен и менее портативен), я хотел бы указать на очень приятный функциональный аспект: хотя некоторые элементы синтаксиса, такие как case, являются встроенными, полученные конструкции не отличаются от любых других заданий. Их можно комбинировать так же:

if case $HOST in node*) true;; *) false;; esac; then
    # Ваш код здесь
fi

Или даже короче:

if case $HOST in node*) ;; *) false;; esac; then
    # Ваш код здесь
fi

Или даже короче (просто чтобы продемонстрировать ! как элемент языка — но это плохой стиль):

if ! case $HOST in node*) false;; esac; then
    # Ваш код здесь
fi

Если вам нравится быть явным, создайте свой собственный элемент языка:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }

Разве это не очень приятно?

if beginswith node "$HOST"; then
    # Ваш код здесь
fi

Поскольку sh в основном представляет собой только задания и списки строк (и внутренние процессы, из которых состоят задания), мы можем даже заниматься легким функциональным программированием:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
checkresult() { if [ $? = 0 ]; then echo TRUE; else echo FALSE; fi; }

all() {
    test=$1; shift
    for i in "$@"; do
        $test "$i" || return
    done
}

all "beginswith x" x xy xyz ; checkresult  # Выводит TRUE
all "beginswith x" x xy abc ; checkresult  # Выводит FALSE

Это элегантно. Не то чтобы я рекомендовал использовать sh для чего-то серьезного — он слишком быстро ломается при реальных требованиях (нет лямбд, поэтому мы вынуждены использовать строки. Но вложенные вызовы функций со строками невозможны, пайпы невозможны и т.д.)

0

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

case "$HOST" in 
    user1|node*) 
        echo "yes";;
    *)
        echo "no";;
esac

Правка:

Я добавил ваши альтернативы в оператор case выше.

В вашей отредактированной версии у вас слишком много скобок. Правильный вариант должен выглядеть так:

if [[ $HOST == user1 || $HOST == node* ]]; then
    echo "yes"
else
    echo "no"
fi
0

В Bash символ # используется для обозначения комментариев, что создает некоторые сложности при работе с такими строками. Однако я нашёл следующее решение:

Мне также больше нравится заключать строки в кавычки, чтобы избежать проблем с пробелами и другими символами.

Вот пример кода:

A="#sdfs"
if [[ "$A" == "#"* ]]; then
    echo "Пропустить строку комментария"
fi

Таким образом, если переменная A начинается с символа #, программа выведет "Пропустить строку комментария".

0

Добавляя немного больше синтаксиса к ответу Марка Рушакоффа с наивысшим рейтингом.

Выражение

$HOST == node*

можно также записать как

$HOST == "node"*

Эффект остается тем же. Просто убедитесь, что подстановочный знак находится вне кавычек. Если же подстановочный знак окажется внутри кавычек, он будет интерпретироваться буквально (т.е. не как подстановочный знак).

0

Ваш код на Bash проверяет, начинается ли строка word с буквы "a". Вот перевод с объяснением:

word="appel"

if [[ $word = a* ]]
then
  echo "Начинается с a"
else
  echo "Нет совпадения"
fi

Здесь [[ $word = a* ]] — это условие, которое использует шаблон для проверки, начинается ли переменная word с буквы "a". Если условие истинно, выводится сообщение "Начинается с a", иначе — "Нет совпадения".

Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь