Diferencia entre {1,2,3} y {1..3}

17

¿Hay alguna diferencia entre las secuencias {1,2,3}y {1..3}?

Por ejemplo si tengo algunos archivos

file.1
file.2
file.3

y los quiero catjuntos ¿es seguro usarlos cat file.{1..3} > file?

Lo que sé es que cat file.*>filepodría causar problemas porque el shell puede expandir los archivos de forma aleatoria a veces (creo que esto depende de los inodes, ¿no?)

syss
fuente
1
usocat file.[123] >file
mikeserv
3
El orden de expansión de file.*no depende de los inodes. Siempre los ordena lexicográficamente, lo que podría depender de su configuración de localización.
Barmar
1
"depende de los inodes" suena como una fase de una de las escenas de "computadora" criminal-mente-eqsue mejor investigadas.
Alec Teal
1
@mikeserv, creo que lo tengo, es un globo de shell, por lo que solo se expande a los archivos que realmente existen, ¿verdad? Vs. file.{1..3}que se expande a los tres si existen o no.
Comodín
1
@Wildcard: derecha, siempre que exista al menos una, es decir. Si no, no se expande en absoluto y los caterrores file.[123] not foundo algo muy útil.
mikeserv

Respuestas:

18

{1..3}y {1,2,3}producen el mismo resultado, pero de manera diferente.

En general, {n1..n2}(que fue primero de zsh, bashy kshcopiado más tarde) donde n1y n2son números enteros que producen todos los números entre n1y n2. Mientras {x,y,z}producen tres personajes x, yy z.

En su caso, es seguro usar cat file.{1..3} > file

Ahora, en el caso de cat file.*>file, usó el globbing de shell , que produce el inicio de todos los nombres de archivo file.y el resultado se ordenará según el orden de clasificación en el entorno local actual.

Todavía está a salvo, pero ya no cuando tiene más de 10 archivos. {1..10}le dará 1 2 3 4 5 6 7 8 9 10. Mientras que con globbing, obtendrás1 10 2 3 4 5 6 7 8 9

Cuonglm
fuente
8

La diferencia es que una es una lista y la otra una secuencia. {1,2,3}expande a tres elementos específicos, 1, 2, y 3. {1..3}se expande a la lista de números entre uno y tres. En este caso particular, son iguales y puede usar cualquiera de los dos. file.*se expandirá a todos los archivos y directorios en el directorio actual cuyo nombre comienza con file.. Si solo tienes file.1, file.2y file.3eso también es equivalente a los otros dos.

En cuanto a que causa problemas, no veo por qué. Tal vez estés pensando en

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

Eso, sin embargo, es un tema completamente diferente. El único otro problema que se me ocurre es que su shell podría no enumerar los archivos en el orden correcto. Por ejemplo:

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

Para resolver eso, puede usar en zshlugar de bash(ver aquí para más detalles):

% echo f*(n)
file1 file2 file11

En general, los tres enfoques no son lo mismo. Depende de lo que quieras hacer. En los casos en que los tres devuelven la misma salida, sí, puede usar cualquiera de ellos. No hace ninguna diferencia. Todas estas expansiones las realiza el shell y suceden antes de pasarlas a cualquier comando que las use.

terdon
fuente
¿no habría un problema *si tuviera más o igual a 10 archivos, si dependiera del orden correcto?
syss
1
@syss no. Sería un problema si tuvieras más de ARG_MAXarchivos, pero eso será mucho más que 10.
terdon
1
@terdon Estaba preguntando si aparecerían en orden numérico (es decir, no "1, 10, 2"), no si desbordarían la matriz de argumentos.
Random832
3
@terdon Creo que @syss tiene razón en que la salida de cat *no está bien definida. El resultado depende del shell y del entorno. Ver el comentario de Sebastian .
Marco
¿No agregará .txtresolver el problema con file.*?
Ismael Miguel
6

Son iguales, pero depende de la versión de bash que haya instalado si están disponibles.

Desde esta página:

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

{a..z} introduced in bash 3

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