В чем разница между a[bc]d
и a{b,c}d
? Почему люди используют, a{b,c}d
когда уже есть a[bc]d
?
ls
и вы когда-нибудь попробуете только отдельные символы, они будут работать одинаково.
В чем разница между a[bc]d
и a{b,c}d
? Почему люди используют, a{b,c}d
когда уже есть a[bc]d
?
ls
и вы когда-нибудь попробуете только отдельные символы, они будут работать одинаково.
Ответы:
Два совершенно разные.
a[bc]d
это шаблон файла (в оболочках, кроме fish
). Он расширится до двух имен файлов abd
и, acd
если это имена существующих файлов в текущем каталоге.
[...]
Часть представляет собой квадратные скобки выражение , которое соответствует одному символу из перечисленных (или элементы которых объединяются , когда диапазоны включены). Чтобы соответствовать шаблону a[bc]d
, символ между строками a
и d
именем файла должен быть либо a, b
либо a c
.
Если abd
существует, но acd
не существует, то он будет только расширяться abd
, и наоборот.
Если ни один abd
, ни acd
существовать, в зависимости от оболочки и вариант, это вызовет ошибку (оригинал Unix sh
, (t)csh
, zsh
,fish
, bash -O failglob
) и , возможно , выйти из оболочки, или оставить шаблон unexpanded¹ (Bourne-подобные и rc
-как оболочки) или расширяться ничего ( bash/zsh/yash -o nullglob
некоторые старые версии fish
Unix, sh
и (t)csh
если в той же команде есть другие совпадающие глобусы).
a{b,c}d
это расширение скобки (в оболочках, которые их поддерживают). Это расширится до двух строк abd
и acd
.
{...}
Часть представляет собой разделенные запятые набора строк (в данном примере, в некоторой оболочке, он также может представлять собой диапазон , такие как a..k
или 20..25
или более продвинутых из них , как 00..20..2
и 0..20..2%02d
), а также расширение вычисляется путем объединения каждого из этих строк с фланкирующим струны a
и d
. Эти строки могут быть длиннее одного символа и также могут быть расширениями скобок.
Расширение происходит независимо от того, соответствуют ли эти строки существующим именам файлов или нет.
Если вы строите строки, используйте расширение скобки. Если вы соответствуете именам файлов, используйте шаблон имени файла.
¹ В данном конкретном случае a[bc]d
может оказаться имя существующего файла, поэтому использование таких вещей, как rm -f ./*.[ch]
в этих оболочках , потенциально опасно и rm -f ./*.{c,h}
представляет меньшую проблему.
a{b,c}d
, что в , b
и c
части не должны быть отдельными буквами; например ex{ten,ci}sion
. Хотя ex[tenci]sion
или что-то будет соответствовать только одной из этих букв.
a[bc]d
является сопоставлением с образцом и является частью стандарта POSIX. В POSIX это вводится как «выражение скобки образца». Это задокументировано в разделе 2.13 руководства
Если без кавычек и вне выражения в скобках, следующие три символа должны иметь особое значение в спецификации шаблонов:
?
Знак вопроса - это шаблон, который должен соответствовать любому символу.
*Звездочка - это шаблон, который должен соответствовать нескольким символам, как описано в разделе «Шаблоны, соответствующие нескольким символам».
[Открытая скобка должна вводить выражение скобки.
В разделе 2.13.3 также упоминается то, что он ведет себя не так, как можно ожидать от обычных регулярных выражений, когда он используется для расширения имени файла (выделено мной).
Правила, описанные до сих пор в «Шаблонах, совпадающих с одним символом», и «Шаблонах, совпадающих с несколькими символами», квалифицируются по следующим правилам, которые применяются, когда для расширения имени файла используется нотация «Шаблон соответствия»:
Символ косой черты в имени пути должен явно совпадать с использованием одной или нескольких косых черт в шаблоне; он не должен совпадать ни со специальными символами звездочки или знака вопроса, ни с выражением в скобках. Трещины в шаблоне должны быть определены до выражения в скобках; таким образом, косая черта не может быть включена в выражение скобки шаблона, используемое для расширения имени файла. Если символ косой черты обнаруживается после неэкранированного символа открытой квадратной скобки до того, как будет найдена соответствующая заключительная квадратная скобка, открытая скобка должна рассматриваться как обычный символ. Например, шаблон
"a[b/c]d"
не соответствует таким путям какabd
илиa/d
. Это соответствует только пути в буквальном смыслеa[b/c]d
.
a{b,c}d
это расширение скобок , это не в спецификации POSIX. Вот соответствующая часть из Баш руководства (выделено мной):
Разбивка скобок - это механизм, с помощью которого можно генерировать произвольные строки . Этот механизм похож на расширение имени файла (см. Расширение имени файла), но генерируемые имена файлов не должны существовать . Шаблоны, которые должны быть развернуты в фигурные скобки, принимают форму необязательной преамбулы, за которой следует либо последовательность строк, разделенных запятыми, либо выражение последовательности между парой фигурных скобок, за которым следует дополнительный постскриптум. Преамбула имеет префикс к каждой строке, содержащейся в фигурных скобках, а затем к каждой результирующей строке добавляется постскриптум, расширяющийся слева направо.
Согласно комментарию @mosvy, это впервые появилось из, csh
но поведение в bash
отличается от csh
других оболочек. Этот тип расширения фигурных скобок также присутствует в glob(3)
.
Существует еще один тип расширения фигурных скобок, {a..z}
который появился только после bash
3.0, а в bash
4.0 добавлено больше .
В оболочке, где включено глобирование, выполнить в пустой папке, возвращается следующий результат
$ echo a[bc]d
a[bc]d
$ echo a{b,c}d
abd acd
В ответ на комментарий @ Jesse_b, если вы работаете в интерактивной оболочке и оба они применимы, a[bc]d
набрать текст будет меньше проблем. Например grep pattern [ab][12].txt
.
csh
, задолго до bash
. Он также присутствует в библиотечной функции glob (3). Разница в том, что bash
он выполняется до других расширений: a=A; ab=A/B; ac=A/C; echo $a{b,c}
будет работать в bash иначе, чем любая другая оболочка.
command a[bc]d
?