unix - usa - tipos de comodines
¿Qué significan los comodines de doble asterisco? (4)
He probado el siguiente comando pero tengo problemas para interpretarlo:
ls **
pero no estoy seguro exactamente de lo que está generando y por qué ese es el resultado.
Considere el siguiente árbol de directorios:
folderA
├── file1
├── file2
└── folderB
├── file3
└── folderC
ls
todos los objetos en la carpeta actual:
$ ls
file1 file2 folderB
ls *
todos los objetos en la carpeta actual y además un nivel más recursivo
$ ls *
file1 file2
folderB:
file3 folderC
La respuesta de Keith es la correcta. Consulte allí.
El comportamiento exacto de este comodín en particular ha sido bien cubierto por las otras respuestas, pero la información sobre el caso general puede ser útil.
Este comportamiento no se limita a ls
, y se conoce como "globbing", que es la expansión de patrones basados en coincidencias con nombres de archivos existentes. Es importante tener en cuenta que estos patrones no utilizan sintaxis de expresión regular.
El shell procesa previamente los argumentos antes de enviarlos al programa. En general, existen múltiples niveles de expansión, algunos de los cuales involucran globos.
Un gran recurso para obtener más información sobre los otros comodines disponibles en un patrón global de archivos es la página de manual de Unix. Una versión en línea para glob se puede encontrar here .
Finalmente, un ejemplo simple de lo que esto puede hacer por usted, especialmente cuando se combina con otras mejoras de la expansión de shell, en este caso las proporcionadas por el shell bash
. La información sobre las expansiones utilizadas en este ejemplo se puede encontrar en la Guía para principiantes de Bash , que es mi recurso para ir a pesar del título.
ls *{01..04}.{txt,csv}
convierte en ls *01.txt *01.csv *02.txt *02.csv *03.txt *03.csv *04.txt *04.csv
Que podría producir algo como esto:
input_01.txt input_02.txt input_03.txt input_04.txt output_01.csv output_02.csv output_03.csv output_04.csv
Mientras se salta estos:
input_05.txt input_06.txt input_07.txt input_08.txt input_09.txt input_10.txt output_05.csv output_06.csv output_07.csv output_08.csv output_09.csv output_10.csv
Un ejemplo trivial, pero si sabe que este comportamiento no es específico de ls
, entonces puede imaginar la utilidad cuando se combina con mv
, cp
, rsync
, etc.
Es probable que esté utilizando una función especial de algunos shells que le permite **
hacer una coincidencia recursiva, a diferencia de un solo *
, que coincide solo en el directorio actual.
El comodín *
coincide con cualquier archivo o directorio (cuyo nombre no comienza con .
) En el directorio actual.
Dependiendo de qué shell esté utilizando y con qué configuración, **
puede ser equivalente a *
; podría coincidir con cero o más caracteres seguidos de cero o más caracteres, lo que equivale a hacer coincidir cero o más caracteres una sola vez.
Pero con algunos shells, con algunas configuraciones, **
es una versión recursiva de *
, que coincide con todos los archivos y directorios en el directorio y subdirectorios actuales.
Citando el manual de bash
:
`* ''
Coincide con cualquier cadena, incluida la cadena nula. Cuando la opción de shell `globstar ''está habilitada, y se usa` *'' en un contexto de expansión de nombre de archivo, dos `* ''adyacentes usados como un solo patrón coincidirán con todos los archivos y cero o más directorios y subdirectorios. Si le sigue un `/ '', dos` `*'' adyacentes solo coincidirán con los directorios y subdirectorios.
Esto funciona solo si la opción globstar
se establece a través de:
shopt -s globstar
(está deshabilitado de forma predeterminada) y solo en versiones relativamente recientes de bash
.
Creo que zsh también soporta esta sintaxis.
Es importante tener en cuenta que los comodines son expandidos por el shell, no por el comando ls
. Si escribe ls **
, o ls *.txt
, el comando ls
nunca ve los caracteres *
; solo ve una lista expandida de archivos, como si hubiera escrito la lista completa en la línea de comandos.
Similar al comando dir
DOS, la función del comando ls
es listar archivos y directorios. Cuando lo que se debe enumerar es un archivo, el comando simplemente lista el archivo, no es gran cosa. Cuando lo que se debe enumerar es una carpeta, el comando enumera los contenidos de la carpeta. Además, si solo el comando ls
sin argumentos, lo que se debe enumerar por defecto es el directorio de trabajo o la carpeta actual. (Además, el nombre de la carpeta actual siempre es .
, Por lo que el comando ls
básico es equivalente a ls .
.)
Ejemplo: Tiene en su carpeta actual un archivo llamado file_001
, una carpeta llamada folder_002
, y en la carpeta tiene archivos llamados picture_003
y picture_004
. Cuando escriba ls
, verá file_001 folder_002
, y cuando escriba ls folder_002
, verá picture_003 picture_004
.
En Unix, el procesamiento de comodines es realizado por el shell. Cuando escribe ls **
, su shell procesa el **
, antes de ejecutar el comando ls
, reemplaza el **
con los nombres de todos los archivos / carpetas que coinciden. (El comodín *
coincide con cualquier archivo o carpeta. Usar **
coincide con cualquier archivo o carpeta cuyo nombre comience con cualquier cosa y termine con cualquier cosa, por lo que es funcionalmente equivalente a solo *
.)
En este caso, cuando se ejecuta el comando ls
, los argumentos de la línea de comandos son una lista de todos los archivos y carpetas en la carpeta actual, como si los hubiera escrito todos ustedes mismos. Entonces, en nuestro ejemplo, ahora está ejecutando el comando ls file_001 folder_002
. Cuando el comando ls
procesa su línea de comando, el primer elemento es un archivo, por lo que simplemente enumera el archivo y el segundo elemento es una carpeta, por lo que enumera el contenido de la carpeta. Además, dado que el comando incluye más de una cosa, imprime una etiqueta con el nombre de la carpeta, de modo que puede diferenciar el contenido de la carpeta en la lista de salida de cualquier otra cosa que también esté incluida. Como resultado, la salida del comando ls **
se verá así:
file_001
folder_002:
picture_003 picture_004`
Aunque soy curioso. ¿Qué guía, libro o documento sugiere que pruebe el comando ls **
?