12

Я часто нахожу это в сценариях (и, должен признать, сам это пишу):

a=$(echo "$x" | sed "s/foo/bar/")

или же

if echo "$x" | grep -q foo
then
    ...
fi

Рассмотрим "foo", чтобы включить некоторые регулярные выражения.

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

Я просто не могу найти это. Кто-нибудь?

4 ответа4

10

Если вы не примете определенную оболочку, нет лучшего способа сделать это, чем «pipe echo to tool» (или просто сам «инструмент», такой как expr); это все, на что вы действительно можете рассчитывать с традиционной оболочкой Bourne и / или оболочкой POSIX. Если вы рассматриваете другие оболочки, то есть некоторые другие встроенные возможности.

Кш имеет

  • дополнительные шаблоны ?(pattern-list) , *(pattern-list) , {n}(pattern-list) , {n,m}(pattern-list) , @(pattern-list) !(pattern-list) ;
  • спецификатор %P printf для преобразования расширенного регулярного выражения в шаблон (и %R для расширенного регулярного выражения в шаблон);
  • условие expr == pattern в тестах [[ expr ]] ;
  • расширение параметра ${param/pattern/replacement} .

Баш имеет

  • опция extglob для включения большинства дополнительных шаблонов ksh (нет {n} и {n,m});
  • условие expr == pattern (в тестах [[ expr ]]);
  • расширение параметра ${param/pattern/replacement} ;
  • (в более новых версиях) условие expr =~ extregexp (в тестах [[ expr ]]), которое может соответствовать расширенным регулярным выражениям
    • с заключенными в скобки подвыражениями и параметром BASH_REMATCH можно было бы выполнить замены в стиле sed .

зш имеет

  • свои собственные расширенные шаблоны с опцией EXTENDED_GLOB ;
  • ksh- подобные расширенные шаблоны с опцией KSH_GLOB ;
  • условие expr == pattern (в тестах [[ expr ]] );
  • расширение параметра ${pattern/pattern/replacement} ;
  • условие expr =~ extregexp (в тестах [[ expr ]] ), которое может соответствовать расширенным регулярным выражениям,
    • он может использовать PCRE вместо простых расширенных регулярных выражений, если установлена опция RE_MATCH_PCRE,
    • с подвыражением в скобках, параметр MATCH и параметр match (или BASH_REMATCH с установленной опцией BASH_REMATCH SED -Style замена может быть сделана;
  • модуль zsh/pcre который предлагает команды pcre_compile , pcre_study и pcre_match и условие проверки -pcre-match (в тестах [[ expr ]] );
  • модуль zsh/regex который предлагает условие проверки -regex-match (в тестах [[ expr ]] ).
7
sed 's/foo/bar/' <<< "foobie"

grep 'this' <<< "this or that"

Хотя ответы Дэна МакГа хорошие, они не дадут такую же поддержку регулярного выражения, если она вам понадобится.

6

Чтобы заменить строку sed, сделайте что-то вроде

${a/foo/bar} или ${a//foo/bar}

В первой форме заменяется только первый экземпляр. Вторая форма - это глобальный поиск и замена.

В вашем случае это было бы

Вместо:

if echo $x | grep foo
then
    ...
fi

Рассмотрите возможность использования:

if [ $x =~ foo ]
then
    ...
fi

Где foo - это регулярное выражение.

2

Хороший способ, совместимый с posix, для тестирования, если переменная содержит шаблон:

test ${var##*foo*} || <do something>;

Синтаксис расширения параметра :

 ${parameter##pattern}

где pattern это шаблон оболочки.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .