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

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

Creé tres archivos en mi directorio usando el comando touch inv{1..3}.txt. Ahora usé dos comandos y su resultado es prácticamente el mismo. Esos dos comandos son ls inv[13].txty ls {1,3}.txt.

Entonces, ¿en qué se diferencian estos dos? ¿En qué se diferencian los corchetes de las llaves? También estaba buscando en Google "linux [..]", pero no pude encontrar nada, así que ¿podría saber cómo se llaman estas cosas en la terminología de Linux?

Gracias

Respuesta1

  • {}se llama expansión de llaves. Tiene dos formas: {x..y}y {x,y}, reemplaza 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á a solo x, y. Por ejemplo, {2,5}se ampliará a 2y 5.

    Si no es posible ninguna 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 cualquier coincidencia de archivo, durante la creación/coincidencia de archivos.

  • []se conoce como patrón de expansión de nombre de ruta (o global). A diferencia de la expansión de llaves, solo puede usarla mientras coincide con nombres de archivos; 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 dentro de los corchetes por separado, es decir, cada carácter se trata individualmente. Entonces, for [25].txtcoincidirá con un archivo llamado 2.txto 5.txten el directorio actual, mientras que for [245].txtcoincidirá con cualquier archivo llamado 2.txto 4.txto 5.txt.

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


Una diferencia de comportamiento importante entre estos dos es cuando hay más patrones que igualar, mientras que en realidad hay menos que coincidan. Como la expansión de llaves se realiza pase lo que pase, mostrará un error de que ciertos archivos no existen, mientras que la expansión del nombre de ruta coincidirá con todo 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 del nombre de ruta está definido por POSIX, por lo que es portátil entre Bourne Shell y sus derivados.

La expansión de llaves {}, no está definida por POSIX, por lo tanto, no es portátil entre todos los shells. Por ejemplo, dash( shen Ubuntu) no tiene esto. Fue tomado prestado cshy funcionará solo en ciertos shells, por ejemplo bash, zsh, ksh93, fish. Asegúrese de que el shell que está utilizando admita esto 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

Respuesta2

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. Esto esexpansión del nombre de ruta.

inv{1,5}.txtse expande inv1.txtindependientemente inv5.txtde qué archivos se encuentran realmente en su sistema de archivos. Esto esexpansión de corsé.

información relacionada