В чем разница между ls [13] и ls {1,3}?

11

Я создал три файла в своем каталоге с помощью команды touch inv{1..3}.txt. Теперь я использовал две команды, и их вывод практически одинаков. Эти две команды ls inv[13].txtи ls {1,3}.txt.

Так как же эти два разных? Чем квадратные скобки отличаются от фигурных скобок? Кроме того, я гуглил «linux [..]», но ничего не смог найти, так мог ли я узнать, как эти вещи называются в терминологии linux?

Спасибо

posixKing
источник
2
Название для этого - «расширение имени файла» или «globbing».
Byte Commander
Что из этого является расширением или добавлением имени файла? Это квадратная скобка ([..]) или цветочная скобка ({..})?
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
heemayl
источник
1
Следует избегать полагаться на поведение [ ]расширения при отсутствии совпадений, поскольку оно может различаться в зависимости от конфигурации оболочки. Если вы хотите использовать [или ]в имени файла, оно должно быть указано в ваших командах. Также стоит заметить разницу между {13..79}и [13-79]. Первым будет производить все числа в диапазоне от 13до 79, то второй будет соответствовать символам 1, 3, 4, 5, 6, 7, и 9.
Касперд
@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независимо от того, какие файлы на самом деле находятся в вашей файловой системе. Это расширение скобки .

John1024
источник
Другое ключевое отличие заключается в том, что вы можете писать, ba{con,tman}и нет эквивалента в квадратных скобках. IOW, расширение скобки не только для отдельных символов.
Хоббс