Diferença entre {1,2,3} e {1..3}

17

Existe uma diferença entre as sequências {1,2,3}e {1..3}?

Por exemplo, se eu tiver alguns arquivos

file.1
file.2
file.3

e eu quero cateles juntos, é seguro usar cat file.{1..3} > file?

O que eu sei é que isso cat file.*>filepode causar problemas porque o shell pode expandir os arquivos de maneira aleatória, às vezes (acho que isso depende dos inodes, não é?)

syss
fonte
1
usecat file.[123] >file
mikeserv
3
A ordem de expansão de file.*não depende dos inodes. Ele sempre os classifica lexicograficamente, o que pode depender da sua configuração de localização.
Barmar 18/11/2015
1
"depende dos inodes" soa como uma fase de uma das cenas mais bem pesquisadas do "computador" de mentes criminosas eqsue.
Alec Teal
1
@ MikeServ, acredito que entendi - é um shell glob, então ele só se expande para arquivos que realmente existem, certo? Vs. file.{1..3}que se expande para os três, existindo ou não.
Curinga
1
@Wildcard - certo, contanto que exista pelo menos um. Caso contrário, ele não se expande e caterros com file.[123] not foundou algo muito útil.
mikeserv

Respostas:

18

{1..3}e {1,2,3}produzir o mesmo resultado, mas de maneira diferente.

Em geral, {n1..n2}(o que veio primeiro a partir zsh, bashe kshcopiados-lo mais tarde) onde n1e n2são inteiros produzir todos os números entre n1e n2. Enquanto {x,y,z}produz três caracteres x, ye z.

No seu caso, você está seguro para usar cat file.{1..3} > file

Agora, no caso de cat file.*>file, você usou o shell globbing , que produz todo o nome de arquivo iniciado file.e o resultado será classificado com base na ordem de intercalação no código de idioma atual.

Você ainda está seguro, mas não mais quando tiver mais de 10 arquivos. {1..10}vai te dar 1 2 3 4 5 6 7 8 9 10. Enquanto estiver com globbing, você terá1 10 2 3 4 5 6 7 8 9

cuonglm
fonte
8

A diferença é que uma é uma lista e a outra uma sequência. {1,2,3}se expande para três elementos específicos, 1, 2, e 3. {1..3}expande para a lista de números entre um e três. Nesse caso específico, eles são iguais e você pode usar um dos dois. file.*será expandido para todos os arquivos e diretórios no diretório atual cujo nome começa com file.. Se você tiver file.1, file.2e file.3isso também é equivalente aos outros dois.

Quanto a causar problemas, não vejo o porquê. Você pode estar pensando em

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

Essa, porém, é uma questão completamente diferente. O único outro problema que consigo pensar é que seu shell pode não listar os arquivos na ordem correta. Por exemplo:

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

Para resolver isso, você pode usar em zshvez de bash(veja aqui para detalhes):

% echo f*(n)
file1 file2 file11

Em geral, as três abordagens não são as mesmas. Depende do que você quer fazer. Nos casos em que os três retornam a mesma saída, sim, você pode usar qualquer um deles. Não faz diferença. Todas essas expansões são feitas pelo shell e acontecem antes de serem passadas para qualquer comando que as use.

terdon
fonte
não haveria problema *se eu tivesse mais ou igual a 10 arquivos, se eu dependesse da ordem certa?
precisa
1
@syss no. Seria um problema se você tivesse mais de ARG_MAXarquivos, mas que será muito, muito mais do que 10.
terdon
1
@terdon Ele estava perguntando se eles apareceriam em ordem numérica (ou seja, não "1, 10, 2"), não se eles estourariam a matriz de argumentos.
Random832
3
@terdon Acho @syss está certo que a saída de cat *não está bem definida. A saída depende do shell e do ambiente. Veja o comentário de Sebastian .
Marco
A adição não .txtresolverá o problema file.*?
Ismael Miguel
6

Eles são os mesmos, mas depende da versão do bash que você instalou, se eles estiverem disponíveis.

A partir dessa página:

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

{a..z} introduced in bash 3

{<START>..<END>..<INCR>} new in bash 4
cristi
fonte