¿Cuál es la diferencia entre ls [13] y ls {1,3}?

11

Creé tres archivos en mi directorio usando el comando touch inv{1..3}.txt. Ahora usé dos comandos y su salida es más o menos la misma. Esos dos comandos son ls inv[13].txty ls {1,3}.txt.

Entonces, ¿cómo son estos dos diferentes? ¿En qué se diferencian los corchetes en comparación con los brackets? También busqué en Google "Linux [..]", pero no pude encontrar nada, ¿podría saber cómo se llaman estas cosas en la terminología de Linux?

Gracias

posixKing
fuente
2
El nombre para esto es "expansión de nombre de archivo" o "globalización".
Byte Commander
¿Cuál de estos es expansión o globalización de nombre de archivo? ¿Es el corchete ([..]) o el corchete de flores ({..})?
posixKing

Respuestas:

14
  • {}se llama expansión de llaves. Tiene dos formas: {x..y}y {x,y}, reemplazar xy ycon cualquier valor alfabético o numérico.

    En la primera forma, {x..y}se ampliará a todos los valores desde xhasta y, inclusive. Por ejemplo, {2..5}se ampliará a 2, 3, 4, 5.

    En la segunda forma explícita, {x,y}se ampliará para solamente x, y. Por ejemplo, {2,5}se expandirá a 2y 5.

    Si no es posible la expansión, el patrón se trata literalmente, por ejemplo, en {a..3}.

    Lo importante a tener en cuenta es que la expansión de llaves se realizará (si es posible) independientemente de la coincidencia de cualquier archivo, mientras esté en la creación / coincidencia de archivos.

  • []se conoce como un patrón de expansión de nombre de ruta (o globbing). A diferencia de la expansión de llaves, solo puede usarla mientras coincide con los nombres de archivo, se tratará literalmente si la usa mientras crea archivos.

    Tiene dos formas: [xyz...]y [x-y].

    En la primera forma, coincidirá con cualquier carácter individual dentro de los corchetes por separado, es decir, cada carácter se trata individualmente. Entonces, para [25].txtque coincida con un archivo llamado 2.txto 5.txten el directorio actual, mientras que para [245].txtque coincida con cualquier archivo llamado 2.txto 4.txto 5.txt.

    En la segunda forma, una expansión de rango se realiza primero antes de hacer coincidir individualmente, si es posible, de lo contrario se tratará literalmente. Entonces [2-5]. txt, coincidirá con cualquier archivo llamado 2.txtor 3.txto 4.txtor 5.txt. Si el rango no se puede ampliar, se tratará literalmente, por ejemplo, en caso de [a-3].txt.


Una diferencia de comportamiento importante entre estos dos es cuando hay más patrones para igualar mientras menos coincide realmente. Como la expansión de llaves se realiza sin importar qué, mostrará un error de que ciertos archivos no existen, mientras que la expansión de la ruta de acceso coincidirá con lo posible sin ningún error para el resto:

$ 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

Nota de portabilidad:

El []operador de expansión ruta de acceso se define por POSIX por lo tanto portátil entre Bourne shell y derivados.

{}POSIX no define la expansión de llaves, por lo tanto, no es portátil entre todos los shells. Por ejemplo, dash( shen Ubuntu) no tiene esto. Fue tomado de cshy trabajará en ciertas conchas única por ejemplo bash, zsh, ksh93, fish. Asegúrese de que el shell que está utilizando lo admite antes de implementarlo.


Ejemplo:

$ 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
fuente
1
Se debe evitar confiar en el comportamiento de [ ]expansión cuando no hay coincidencias porque eso puede ser diferente dependiendo de la configuración del shell. Si desea usar [o ]en un nombre de archivo, debe citarse en sus comandos. También vale la pena notar la diferencia entre {13..79}y [13-79]. El primer producirá todos los números en el rango de 13a 79, la segunda coincidirá con los personajes 1, 3, 4, 5, 6, 7, y 9.
kasperd
@kasperd Sí, para eso es nullglob(o similar). Sobre la [13-79]coincidencia, creo que mencioné claramente en mi respuesta sobre el comportamiento por carácter de [] `.
heemayl
@heemayl Creo que también valdría la pena mencionar que la forma `{1..3}` es bashismo. Esto no funcionará en el tablero. Creo que kshtiene esta característica, pero no son sabores más modernos, como mksh y pkdsh
Sergiy Kolodyazhnyy
@Serg Se agregó la nota de portabilidad.
heemayl
7

La diferencia clave entre las dos formas se ilustra aquí:

$ 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].txtes un globo y expandirá la lista de archivos coincidentes en su sistema de archivos. Esta es la expansión del nombre de ruta .

inv{1,5}.txtse expande inv1.txte inv5.txtindependientemente de qué archivos están realmente en su sistema de archivos. Esta es la expansión de llaves .

John1024
fuente
La otra diferencia clave es que puedes escribir ba{con,tman}y no hay equivalente usando corchetes. IOW, la expansión de llaves no es solo para caracteres individuales.
hobbs