Вот несколько вариантов на ту же тему. All создает команду с именем gitoff
, которая выполнит git push
, за которым следует sudo shutdown -h now
, если отправка прошла успешно.
alias gitoff='git push && sudo shutdown -h now'
gitoff () {
git push && sudo shutdown -h now
}
gitoff () {
if git push; then
sudo shutdown -h now
fi
}
gitoff () {
if git push; then
sudo shutdown -h now
else
echo >&2 'git push failed, no shutdown'
fi
}
Здесь есть разные проблемы. Прежде всего, выражение ^[ ]w
означает :найти начало строки, затем ровно один пробел, затем w
. Так что на самом деле работает отлично. Если вы хотите, чтобы он соответствовал одному или нескольким пробелам, вам нужно добавить классификатор к классу символов [ ]
:
$ grep '^[ ]\+w' text.txt
whitespace 1
whitespace 2
+
означает «один или несколько». Вариант регулярных выражений по умолчанию, используемый grep
, называется базовым регулярным выражением BRE (), и в этом варианте регулярного выражения +
необходимо экранировать, поэтому \+
выше*. Кроме того, вы можете использовать расширенные регулярные выражения ERE (), передав флаг -E
, или PCRE (Perl-совместимые регулярные выражения ), передав флаг -P
. С этими вариантами регулярных выражений вам не нужно экранировать +
, чтобы он действовал как квантификатор:
$ grep -P '^[ ]+w' text.txt
whitespace 1
whitespace 2
$ grep -E '^[ ]+w' text.txt
whitespace 1
whitespace 2
Следующая и более важная проблема заключается в том, что вы не цитируете регулярное выражение. Заключение в кавычки необходимо для того, чтобы регулярное выражение передавалось вgrep
как есть , а не сначала интерпретировалось оболочкой. Однако, поскольку вы не цитируете его, он расширяется оболочкой до того, как будет передан grep
. Вы можете проверить это, используя опцию set -x
, чтобы оболочка распечатала, что она делает:
$ set -x
$ grep ^[ ]{0,}w text.txt
+ grep '^[' ']0w' ']w' text.txt
grep: Invalid regular expression
Во-первых, поскольку между ^[
и ]
есть пробел, оболочка интерпретирует это как два отдельных аргумента:^[
и ]{0,}w
. Но {}
используются в оболочке для расширения скобок. Например:
$ echo foo{a,b}
fooa foob
Но когда вторая часть расширения пуста, вы получаете:
$ echo foo{a,}
fooa foo
Таким образом, расширение ]{0,}w
становится:
$ echo ]{0,}w
]0w ]w
И в результате, и как вы можете видеть в выводе set -x
выше, эти три аргумента фактически передаются вgrep
:
'^[' ']0w' ']w'
Но если вы их цитируете, их нужно экранировать при использовании BRE,точно так же, как +
выше:
$ grep '^[ ]\{2\}w' text.txt
whitespace 2
Последнее замечание :[ ]
точно такое же, как , нет смысла использовать класс символов для одного символа.
Объединяя все это, чтобы соответствовать ровно одному пробелу в начале строки, используйте:
$ grep '^ w' text.txt
whitespace 1
Чтобы сопоставить один или несколько, используйте:
$ grep '^ \+w' text.txt
whitespace 1
whitespace 2
Или:
$ grep -E '^ +w' text.txt
whitespace 1
whitespace 2
или
$ grep -P '^ +w' text.txt
whitespace 1
whitespace 2
Для соответствия определенному диапазону номеров (, например. 0, 1 или 2 пробела):
$ grep '^ \{0,3\}w' text.txt
whitespace 0
whitespace 1
whitespace 2
или
$ grep -P '^ {0,3}w' text.txt
whitespace 0
whitespace 1
whitespace 2
или
$ grep -E '^ {0,3}w' text.txt
whitespace 0
whitespace 1
whitespace 2
И чтобы соответствовать определенному номеру, либо установите этот номер в {}
, как показано выше, либо просто повторите символ N раз:
$ grep '^ \{2\}w' text.txt
whitespace 2
$ grep '^ w' text.txt
whitespace 1
$ grep '^ w' text.txt
whitespace 2
Ивсегда цитируйте ваши регулярные выражения!
*На самом деле, в POSIX BRE +
не имеет специального значения, но BRE, реализованный GNU grep
, распознает его, если он экранирован.
Правильная команда:
Используйтеgrep -E '^[ ]{0,}' text.txt
-E, --extended-regexp Interpret PATTERN as an extended regular expression (ERE, see below).
Причина, по которой не работает:
Не используя одинарные кавычки вокруг регулярного выражения, bash откроет его, и ваша команда станет
grep '^[' ] ]0 text.txt
, что переводится как grep с регулярным выражением '^['
в файлах ]
, ]0
и text.txt
^[
неверно, так как [
— это специальный символ, который также требует закрывающего символа ]
Почему -Вариант E:
{m,n} является расширенным регулярным выражением, и для его использования grep требуется -параметр E