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

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

export PATH="/home/username/anaconda/bin:$PATH"
export PATH="/usr/local/share/rsi/idl/bin:$PATH"    

Другой вариант - просто изменить существующую строку на эту:

export PATH="/home/username/anaconda/bin:/usr/local/share/rsi/idl/bin:$PATH"
5
17.06.2017, 22:30
3 ответа

В bash3.2 или выше и если совместимость с 3.1 не включена (с опцией compat31или BASH_COMPAT=3.1), цитирование операторов регулярных выражений (не только с \, но и с любым из операторы bashв кавычках ('...', "...", $'...',$"..."))лишают их особого смысла.

[[ $var =~ 'OK$' ]]

соответствует только в строках, содержащих OK$буквально (, где $соответствует литералу$)

[[ $var =~ OK$ ]]

соответствует строкам, которые заканчиваются на OK(, что $является оператором RE, который соответствует в конце строки ).

Это также относится к регулярным выражениям, хранящимся в переменных, или к результату некоторой замены.

[[ $var =~ $regexp ]]   # $var matches $regexp
[[ $var =~ "$string" ]] # $var contains $string

Обратите внимание, что это может стать неудобным, поскольку есть некоторые символы, которые необходимо заключать в кавычки для синтаксиса оболочки (, например пробелы, <, >, &, круглые скобки, если они не совпадают ). Например, если вы хотите сопоставить с .{3} <> [)}]&regexp (3 символа, за которыми следует " <> ", )или }и &), вам нужно что-то вроде:

[[ $var =~.{3}" <> "[}\)]\& ]]

Если вы сомневаетесь, какие символы нужно заключать в кавычки, вы всегда можете использовать временную переменную . Это также означает, что он сделает код совместимым с bash31, zshили ksh93:

.
pattern='.{3} <> [})]&'
[[ $var =~ $pattern ]] # remember *not* to quote $pattern here

Это также единственный способ, (кроме использования compat31опции (или BASH_COMPAT=3.1)), вы можете использовать не -расширенные операторы POSIX регулярных выражений вашей системы.

Например, чтобы \<считалось границей слова, как во многих механизмах регулярных выражений, вам нужно:

pattern='\<word\>'
[[ $var =~ $pattern ]]

Делать:

[[ $var =~ \<word\> ]]

не будет работать, так как bashобрабатывает эти \как операторы кавычек оболочки и удаляет их перед передачей <word>в библиотеку регулярных выражений.

Обратите внимание, что в ksh93 все гораздо хуже,:

[[ $var =~ "x.*$" ]]
Например,

будет соответствовать whatever-xa*, но не whatever-xfoo. Цитата выше лишает *особого смысла, но не .и не $.

zshповедение проще :кавычки не меняют значения операторов регулярных выражений (как в bash31 )что делает поведение более предсказуемым (вместо этого можно использовать регулярные выражения PCRE ЭРЭ (сset -o rematchpcre)).

yashне имеет конструкции [[...]], но встроенная функция [имеет оператор =~(также вzsh). И, конечно же, [является обычной командой, поэтому заключение в кавычки не может повлиять на интерпретацию операторов регулярных выражений.


Также обратите внимание, что, строго говоря, ваш $sсодержит не 3 строки, а 2 полные строки, за которыми следует бесконечная строка. Он содержит hello\nworld\nOK. В расширенном регулярном выражении OK$оператор $будет соответствовать только концу строки .

В 3 -полных -строках строка , например hello\nworld\nOK\n(, которую вы не сможете получить с помощью подстановки команд в виде полос подстановки команд все в конце символов новой строки ), $будет соответствовать после \n, поэтому OK$не будет соответствовать на нем.

Однако с zsh -o pcrematch$соответствует как в конце строки, так и перед новой строкой в ​​конце строки, если она есть, поскольку она не передает флаг PCRE_DOLLAR_ENDONLYв pcre_compile. Это может показаться плохой идеей, поскольку обычно переменные в оболочках не содержат завершающий символ новой строки, и когда они это делают, мы обычно хотим, чтобы они рассматривались как данные .

12
27.01.2020, 20:34

Малоизвестный факт: caseтоже так делает.

case "$(printf 'hello\nworld\nOK\n')" in
  *$'\nOK') echo "match";;
  *) echo "no match";;
esac

Строка $'...'"C-style" является расширением Bash (которое обеспечивает контекст, в котором escape-коды обратной косой черты, такие как \n, доступны в строках оболочки) , но для переносимости вы можете сказать

*"
OK") echo "match";;

, чтобы получить полностью POSIX-совместимый сценарий оболочки.

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

1
27.01.2020, 20:34

По крайней мере, в bashцитирование RHS приводит к тому, что оно рассматривается как сравнение строк

$ s=$(printf 'hello\nworld\nOK\n')
$ echo "$s"
hello
world
OK
$ [[ "$s" =~ OK$ ]] && echo "match" || echo "no match"
match

тогда как

$ s=$(printf 'hello\nworld\nOK$\n')
$ echo "$s"
hello
world
OK$
$ [[ "$s" =~ 'OK$' ]] && echo "match" || echo "no match"
match
2
27.01.2020, 20:34

Теги

Похожие вопросы