У чому різниця між 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. Ось відповідна частина посібника з bash (наголос мною):
Розширення дужок - це механізм, за допомогою якого можуть формуватися довільні рядки . Цей механізм схожий на розширення імені файлів (див. Розширення імені файлів), але створені імена файлів не повинні існувати . Шаблони, що підлягають розширенню дужок, мають форму необов'язкової преамбули з наступною послідовністю рядків, розділених комами, або вираженням послідовності між парою дужок, а потім необов'язковий постскрипт. Преамбула встановлюється префіксом до кожного рядка, що міститься в дужках, а післяскрипт додається до кожного результуючого рядка, розширюючи зліва направо.
Згідно з коментарем @mosvy, це вперше з'явилося у, cshале поведінка в ньому bashвідрізняється від cshінших оболонок. Цей тип розширень брекетів також присутній у glob(3).
Існує ще один тип розширень брекетів, {a..z}який з’явився лише після bash3.0, а ще більше додано в bash4.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}буде працювати в баші інакше, ніж будь-яка інша оболонка.
command a[bc]d?