bash
Первоначально был разработан в конце 80-х годов как частичный клон ksh
с некоторыми интерактивными функциями из csh / tcsh.
Источники шатания должны быть найдены в тех ранних оболочках, на которых они основаны.
ksh
сам по себе является продолжением оболочки Борна. Сама оболочка Bourne (впервые выпущенная в 1979 году в Unix V7) была чистой реализацией с нуля, но она не полностью отходила от оболочки Thompson (оболочка V1 -> V6) и включала функции оболочки Mashey.
В частности, аргументы команды по-прежнему были разделены пробелами, |
теперь они были новым оператором канала, но ^
все еще поддерживались в качестве альтернативы (а также объясняют, почему вы этого [!a-z]
не делаете [^a-z]
), $1
были по-прежнему первым аргументом в сценарии, а обратная косая черта по-прежнему была escape-символом. , Поэтому многие операторы регулярных выражений ( ^\|$
) имеют особое значение в оболочке.
Оболочка Томпсона опиралась на внешнюю утилиту для глобализации. Когда sh
найден неупомянута *
, [
или ?
S в команде, было бы запустить команду через glob
.
rm *.txt
в итоге запустил glob как:
["glob", "rm", "*.txt"]
и glob заканчивает работу rm
со списком файлов, соответствующих этому шаблону.
grep a.\*b *.txt
будет работать glob
как:
["glob", "grep", "a.\252b", "*.txt"]
*
Выше цитировались, установив 8 - бит на этом символе, предотвращая glob
от лечения его в качестве шаблона. glob
затем удалит этот бит перед вызовом grep
.
Чтобы сделать эквивалент с регулярными выражениями, это было бы:
regexp rm '\.txt$'
Или:
regexp rm '^[^.].*\.txt$'
исключить dot-файлы.
Необходимость избегать операторов, поскольку они удваиваются как специальные символы оболочки, тот факт, что .
в именах файлов часто используется оператор регулярного выражения, делает его не очень подходящим для сопоставления имен файлов и сложным для начинающего. В большинстве случаев все, что вам нужно, это подстановочные знаки, которые могут заменить один ( ?
) или любое число ( *
) символов.
Теперь в разные оболочки добавлены разные операторы сглаживания. В настоящее время глобусы ksh и zsh (и в некоторой степени, bash -O extglob
которые реализуют подмножество глобусов ksh) функционально эквивалентны регулярным выражениям с синтаксисом, который менее громоздок для использования с именами файлов и текущим синтаксисом оболочки. Например, в zsh
(с расширением extendedglob) вы можете сделать:
echo a#.txt
если вы хотите (маловероятно) сопоставить имена файлов, которые состоят из последовательностей, за a
которыми следует .txt
. Проще, чем echo (^a*\.txt$)
(здесь использование фигурных скобок как способ изолировать операторы регулярных выражений от операторов оболочки, которые могли бы быть единственными способами, с которыми оболочки могли бы справиться)
echo (foo|bar|<1-20>).(#i)mpg
Для файлов mpg (без учета регистра), базовым именем которых является foo, bar или десятичное число от 1 до 20 ...
ksh93
теперь может также включать регулярные выражения (базовые, расширенные, perl-подобные или «расширенные») в свои глобусы (хотя они довольно глючные) и даже предоставляет инструмент для преобразования между глобальными и регулярными выражениями ( printf %R
, printf %P
):
echo ~(Ei:.*\.txt)
в матч (не скрытый) TXT файлов с E Xtended регулярных выражений, к регистру I nsensitively.
rm -- ^[^.].*\.txt$
вместоrm -- *.txt
?