Я хотел бы проверить, если строка начинается с "узла", например, "узел001". Что-то вроде
if [ $HOST == user* ]
then
echo yes
fi
Как я могу сделать это правильно?
Кроме того, мне нужно объединить выражения, чтобы проверить, является ли HOST "user1" или начинается с "node"
if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi
> > > -bash: [: too many arguments
Как я могу сделать это правильно?
string
bash
comparison
Тим
источник
источник
Ответы:
В этом фрагменте руководства Advanced Bash Scripting говорится:
Итак, вы поняли это почти правильно; вам нужны двойные скобки, а не одинарные.
Что касается вашего второго вопроса, вы можете написать его так:
Который будет эхом
К
if
синтаксису Bash трудно привыкнуть (IMO).источник
[[ $a == z* ]]
и[[ $a == "z*" ]]
? Другими словами: они работают по-другому? А что конкретно вы имеете в виду, когда говорите "$ a равен z *"?[[ $a == *com ]]
Если вы используете последнюю версию Bash (v3 +), я предлагаю
=~
, например, оператор сравнения Bash regex ,Чтобы сопоставить
this or that
в регулярном выражении, используйте|
, например,Обратите внимание - это «правильный» синтаксис регулярного выражения.
user*
значитuse
и ноль или более вхожденийr
, такuse
иuserrrr
будет совпадать.user.*
означаетuser
и ноль или более вхождений любого символа, а значитuser1
,userX
будет совпадать.^user.*
означает совпадение с шаблономuser.*
в начале $ HOST.Если вы не знакомы с синтаксисом регулярных выражений, попробуйте обратиться к этому ресурсу .
источник
=~
оператор Bash выполняет сопоставление регулярных выражений только в том случае, если правая часть не задана. Если вы цитируете правую часть, «любая часть шаблона может быть заключена в кавычки, чтобы заставить его быть сопоставленным как строка». (1.) всегда ставьте регулярные выражения справа без кавычек и (2.) если вы храните свое регулярное выражение в переменной, НЕ ставьте кавычки в правой части при расширении параметра.Я всегда стараюсь придерживаться POSIX
sh
вместо использования расширений Bash, поскольку одним из основных моментов написания сценариев является переносимость (помимо подключения программ, а не их замены).В
sh
, есть простой способ проверить состояние "is-prefix".Учитывая, насколько стар, тайен и неуклюжий sh (а Bash - не лекарство: он более сложный, менее последовательный и менее переносимый), я хотел бы отметить очень хороший функциональный аспект: хотя некоторые синтаксические элементы, такие
case
как встроенные Полученные конструкции ничем не отличаются от любой другой работы. Они могут быть составлены таким же образом:Или даже короче
Или даже короче (просто представить
!
как элемент языка - но сейчас это плохой стиль)Если вам нравится быть явным, создайте свой собственный элемент языка:
Разве это не очень мило?
А поскольку
sh
в основном это только задания и списки строк (и внутренние процессы, из которых составляются задания), теперь мы можем даже сделать несколько легких функциональных программ:Это элегантно. Не то, чтобы я рекомендовал использовать
sh
для чего-то серьезного - это слишком быстро нарушает требования реального мира (без лямбд, поэтому мы должны использовать строки. Но вложение вызовов функций со строками невозможно, каналы не возможны и т. Д.)источник
case $HOST in user01 | node* ) ...
if case $HOST in node*) true;; *) false;; esac; then
Я видел это здесь и там, на мой взгляд, это выглядит как будто нацарапано.case
команды есть команды, они могут идти внутрьif ... then
.beginswith() { case "$2" in "$1"*) true;; *) false;; esac; }
Иначе должно быть, если оно$1
имеет литерал*
или?
может дать неправильный ответ.Вы можете выбрать только ту часть строки, которую хотите проверить:
Для ответа на следующий вопрос вы можете использовать ИЛИ :
источник
${HOST:0:4}
HOST='a b'; if [ ${HOST:0:4} = user ] ; then echo YES ; fi
Я предпочитаю другие методы, уже опубликованные, но некоторые люди любят использовать:
Редактировать:
Я добавил твои альтернативы к описанию дела выше
В вашей отредактированной версии у вас слишком много скобок. Это должно выглядеть так:
источник
Хотя я нахожу большинство ответов здесь совершенно правильными, многие из них содержат ненужные ошибки. Расширение параметров POSIX дает вам все, что вам нужно:
а также
${var#expr}
полосы наименьшее согласование префиксаexpr
из${var}
и возвращает. Следовательно , если${host}
это не начать сuser
(node
),${host#user}
(${host#node}
) является таким же , как${host}
.expr
позволяетfnmatch()
подстановочные знаки, таким образом${host#node??}
и друзья также работают.источник
[[ $host == user* ]]
может быть необходим башизм , поскольку он гораздо более читабелен, чем[ "${host#user}" != "${host}" ]
. Таким образом, при условии, что вы управляете средой, в которой выполняется скрипт (нацелены на последние версииbash
), предпочтительнее первое.has_prefix()
функцию и больше никогда не смотрел на нее.Поскольку
#
имеет значение в Bash, я получил следующее решение.Кроме того, мне нравится упаковывать строки с "", чтобы преодолеть пробелы и т. Д.
источник
blah:
, похоже, это ответ!Добавление чуть более подробной информации о синтаксисе к ответу самого высокого ранга Марка Рушакова.
Выражение
Может также быть написано как
Эффект тот же. Просто убедитесь, что подстановочный знак находится вне цитируемого текста. Если подстановочный знак находится внутри кавычек, он будет интерпретирован буквально (т.е. не как подстановочный знак).
источник
@OP, для обоих ваших вопросов вы можете использовать case / esac:
Второй вопрос
Или Bash 4.0
источник
;&
доступно только в Bash> = 4.не работает, потому что все
[
,[[
иtest
признать тот же нерекурсивную грамматику. Смотрите раздел УСЛОВНЫЕ ВЫРАЖЕНИЯ на вашей странице руководства Bash.Кроме того, SUSv3 говорит
Вам нужно написать это так, но test не поддерживает это:
test использует = для равенства строк, и что более важно, он не поддерживает сопоставление с образцом.
case
/esac
имеет хорошую поддержку для сопоставления с образцом:У него есть дополнительное преимущество: он не зависит от Bash, а синтаксис переносим. Из спецификации Unix , языка команд оболочки :
источник
[
иtest
встроены в Bash, а также внешние программы. Попробуйtype -a [
.if [ -z $aa -or -z $bb ]
:; ... дает " bash: [: -or: ожидается двоичный оператор "; однакоif [ -z "$aa" -o -z "$bb" ] ; ...
проходит.grep
Забывая о производительности, это POSIX и выглядит лучше, чем
case
решения:Объяснение:
printf '%s'
предотвратитьprintf
расширение обратной косой черты: дословная строка Bash printfgrep -q
предотвращает эхо совпадений с stdout: как проверить, содержит ли файл определенную строку, используя Bashgrep -E
позволяет расширенные регулярные выражения, которые нам нужны для^
источник
Я подправил ответ @ markrushakoff, чтобы сделать его вызываемой функцией:
Используйте это так:
Вот более сложная версия, которая предусматривает указанное значение по умолчанию:
Используйте это так:
источник
Еще одна вещь, которую вы можете сделать, это то
cat
, что вы повторяете, и с трубкойinline cut -c 1-1
источник