Яка різниця між ls [13] та ls {1,3}?


11

Я створив три файли у своєму каталозі за допомогою команди touch inv{1..3}.txt. Зараз я використав дві команди, і їх вихід майже однаковий. Ці дві команди є ls inv[13].txtі ls {1,3}.txt.

То як ці дві різні? Чим квадратні дужки відрізняються від дужок? Також я гуглив за "linux [..]", але нічого не міг знайти, тож чи можу я знати, як називаються ці речі в термінології Linux?

Спасибі


2
Назва для цього - "розширення назви файлів" або "глобалізація".
Байт командир

Яке з них - це розширення чи глобалізація файлів? Це квадратна дужка ([..]) чи квітка ({..})?
posixKing

Відповіді:


14
  • {}називається розширенням дужок. Він має дві форми: {x..y}і {x,y}, замінити xі yбудь-яке буквене або числове значення.

    У першій формі, {x..y}буде розширена на всі значення від xдо y, включно. Наприклад, {2..5}буде розширена 2, 3, 4, 5.

    У другій явній формі, {x,y}буде розширена тільки x, y. Наприклад, {2,5}буде розширено до 2та 5.

    Якщо розширення неможливо, шаблон обробляється буквально, наприклад, в {a..3}.

    Важливо зауважити, що розширення дужок буде здійснено (якщо можливо) незалежно від будь-якого відповідності файлів під час створення / відповідності файлів.

  • []відомий як шаблон розширення (або глобулювання) шляху. На відміну від розширення дужок, ви можете використовувати його лише під час узгодження імен файлів, воно буде розглядатися буквально, якщо ви будете використовувати його під час створення файлів.

    Він має дві форми: [xyz...]і [x-y].

    У першій формі він буде відповідати будь-якому одному символу всередині квадратних дужок, тобто кожен символ розглядається індивідуально. Так [25].txtце буде відповідати файл з ім'ям 2.txtабо 5.txtв поточному каталозі, в той час як для [245].txtнього буде відповідати будь-який файл з ім'ям 2.txtабо 4.txtабо 5.txt.

    У другій формі розширення діапазону проводиться спочатку, перш ніж порівнювати їх окремо, якщо можливо, інакше трактується буквально. Отже [2-5]. txt, він відповідатиме будь-якому файлу з ім’ям 2.txtабо 3.txtабо 4.txtабо 5.txt. Якщо діапазон неможливо розширити, він буде розглядатися буквально, наприклад, у випадку [a-3].txt.


Важливою різницею поведінки між цими двома є те, коли існує більше шаблонів, а менше насправді не відповідає. Оскільки розширення брекетів робиться незалежно від того, воно покаже помилку, що певних файлів (файлів) не існує, тоді як розширення імені шляху буде відповідати всім можливим без будь-якої помилки для решти:

$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt  2.txt  3.txt

$ ls [1-4].txt
1.txt  2.txt  3.txt

Примітка про переносність:

Оператор []розширення імені шляху визначається POSIX, отже портативний серед оболонок і похідних Bourne.

Розширення дужки, {}не визначено POSIX, отже, не є портативним серед усіх оболонок. Наприклад, dash( shв Ubuntu) не має цього. Він був запозичений з cshі буде працювати на деяких оболонках тільки наприклад bash, zsh, ksh93, fish. Переконайтеся, що оболонка, яку ви використовуєте, підтримує це перед реалізацією.


Приклад:

$ touch {1..3}.txt

$ ls {1..3}.txt
1.txt  2.txt  3.txt

$ ls {1,2,3}.txt
1.txt  2.txt  3.txt

$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt  2.txt  3.txt

$ ls {a..3}.txt
ls: cannot access {a..3}.txt: No such file or directory

$ ls [123].txt
1.txt  2.txt  3.txt

$ ls [1-3].txt
1.txt  2.txt  3.txt

$ ls [1-4].txt
1.txt  2.txt  3.txt

$ ls [a-3].txt
ls: cannot access [a-3].txt: No such file or directory

1
Не слід покладатися на поведінку [ ]розширення, коли немає збігів, оскільки це може бути різним, залежно від конфігурації оболонки. Якщо ви хочете використовувати [або ]ім'я файлу, це повинно бути вказано у ваших командах. Також варто помітити різницю між {13..79}і [13-79]. Першим буде виробляти все числа в діапазоні від 13до 79, то другий буде відповідати символам 1, 3, 4, 5, 6, 7, і 9.
kasperd

@kasperd Так, саме для цього nullglob(або подібного). Про [13-79]відповідність, я думаю, я чітко згадував у своїй відповіді про поведінку персонажа [] `.
heemayl

@heemayl Я думаю, що також варто було б згадати, що форма {1..3} `- це башізм. Це не буде працювати в тирі. Думаю, kshє ця особливість, але не більш сучасні аромати, як mksh та pkdsh
Сергій Колодяжний

@Serg Додано примітку про переносимість.
heemayl

7

Ключова різниця між двома формами проілюстрована тут:

$ ls inv[15].txt
inv1.txt
$ ls inv{1,5}.txt
ls: cannot access 'inv5.txt': No such file or directory
inv1.txt

inv[15].txtє глобальним і розширить список відповідних файлів у вашій файловій системі. Це розширення імені .

inv{1,5}.txtрозширюється до inv1.txtта inv5.txtнезалежно від того, які файли є фактично у вашій файловій системі. Це розширення брекетів .


Інша ключова відмінність полягає в тому, що ви можете писати ba{con,tman}і немає еквівалента за допомогою квадратних дужок. IOW, розширення дужок не тільки для окремих символів.
варення
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.