Я создал три файла в своей директории с помощью команды touch inv{1..3}.txt
. Теперь я использовал две команды, и их вывод практически одинаков. Эти две команды — ls inv[13].txt
и ls {1,3}.txt
.
Так чем же они отличаются? Чем квадратные скобки отличаются от фигурных? Я также гуглил "linux [..]", но ничего не нашел, так что могу ли я узнать, как эти вещи называются в терминологии Linux?
Спасибо
решение1
{}
называется раскрытием скобок. Имеет две формы:{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]
.В первой форме он будет соответствовать любому отдельному символу внутри квадратных скобок по отдельности, то есть каждый символ обрабатывается индивидуально. Так, for
[25].txt
он будет соответствовать файлу с именем2.txt
или5.txt
в текущем каталоге, в то время как for[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
решение2
Ключевое различие между этими двумя формами проиллюстрировано здесь:
$ 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
независимо от того, какие файлы на самом деле находятся в вашей файловой системе. Эторасширение скобки.