Разница между {1,2,3} и {1..3}

17

Есть ли разница между последовательностями {1,2,3}и {1..3}?

Например, если у меня есть несколько файлов

file.1
file.2
file.3

и я хочу, чтобы catони вместе были безопасны в использовании cat file.{1..3} > file?

Я знаю, что это cat file.*>fileможет вызвать проблемы, потому что оболочка может иногда случайным образом расширять файлы (я думаю, это зависит от inode, не так ли?)

syss
источник
1
использованиеcat file.[123] >file
mikeserv
3
Порядок расширения file.*не зависит от inode. Он всегда сортирует их лексикографически, что может зависеть от вашего местоположения.
Бармар
1
«зависит от inode» звучит как фаза из одной из «компьютерных» сцен с криминальными умами.
Алек Тил
1
@ mikeserv, я полагаю, я понял - это оболочка, поэтому она распространяется только на файлы, которые действительно существуют, верно? Против file.{1..3}которая распространяется на все три, независимо от того, существуют они или нет.
Wildcard
1
@Wildcard - верно, если хотя бы один существует, то есть. Если нет, то он расширяется совсем не за счет catошибок file.[123] not foundили чего-то очень полезного.
mikeserv

Ответы:

18

{1..3}и {1,2,3}дать тот же результат, но по-другому.

В общем, {n1..n2}(который пришел первый из zsh, bashи kshскопировал его позже) , где n1и n2целые числа производят все числа между n1и n2. Пока {x,y,z}производят три символа x, yа z.

В вашем случае вы безопасно использовать cat file.{1..3} > file

Теперь, в случае cat file.*>file, вы использовали глобирование оболочки , которое выдает все имена файлов, начиная с которых, file.и результат будет отсортирован по порядку сортировки в текущей локали.

Вы все еще в безопасности, но не больше, когда у вас есть более 10 файлов. {1..10}даст тебе 1 2 3 4 5 6 7 8 9 10. В то время как с Globbing, вы получите1 10 2 3 4 5 6 7 8 9

cuonglm
источник
8

Разница в том, что один - это список, а другой - последовательность. {1,2,3}расширяется до трех конкретных элементов, 1, 2, и 3. {1..3}расширяется до списка чисел от одного до трех. В этом конкретном случае они одинаковы, и вы можете использовать любой из двух. file.*развернется ко всем файлам и каталогам в текущем каталоге, имя которого начинается с file.. Если у вас есть file.1, file.2и file.3это тоже эквивалентно двум другим.

Что касается его проблем, я не понимаю, почему. Вы можете думать о

$ cat file.* > file.txt
cat: file.txt: input file is output file

Это, однако, совершенно другая проблема. Единственная проблема, о которой я могу подумать, заключается в том, что ваша оболочка может не перечислять файлы в правильном порядке. Например:

$ touch file1 file11 file2
$ echo file*
file1 file11 file2

Чтобы решить эту проблему, вы можете использовать zshвместо bash( подробности см. Здесь ):

% echo f*(n)
file1 file2 file11

В целом, три подхода не совпадают. Это зависит от того, что вы хотите сделать. В тех случаях, когда три возвращают один и тот же результат, да, вы можете использовать любой из них. Это не имеет значения. Все эти расширения выполняются оболочкой и выполняются до того, как они будут переданы любой команде, которая их использует.

Тердон
источник
не было бы проблемы, *если бы у меня было больше или равно 10 файлов, если я зависел от правильного порядка?
Syss
1
@ нет, нет. Было бы проблемой, если бы у вас было больше, чем ARG_MAXфайлов, но это будет гораздо больше, чем 10.
terdon
1
@terdon Он спрашивал, появятся ли они в числовом порядке (то есть не "1, 10, 2"), не переполняют ли они массив аргументов.
Random832
3
@terdon Я думаю, что @syss прав, что результат cat *не очень хорошо определен. Выход зависит от оболочки и окружающей среды. Смотрите комментарий Себастьяна .
Марко
Разве добавление не .txtрешит проблему с file.*?
Исмаэль Мигель
6

Они одинаковы, но это зависит от версии bash, которую вы установили, если они доступны.

С этой страницы:

{xxx,yyy,zzz,...} probably in all bash versions

{a..z} introduced in bash 3

{<START>..<END>..<INCR>} new in bash 4
Cristi
источник