Imagina un árbol fuente. Hay archivos xml en todas partes.
Pero como hay un XYZ.xml en la raíz de este árbol, no encontrará mis archivos xml.
find -iname *.xml
devoluciones
./XYZ.xml
en vez de
./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml
Imagina un árbol fuente. Hay archivos xml en todas partes.
Pero como hay un XYZ.xml en la raíz de este árbol, no encontrará mis archivos xml.
find -iname *.xml
devoluciones
./XYZ.xml
en vez de
./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml
Respuestas:
find -iname '*.xml'
De lo contrario, se expande su concha *.xml
a XYZ.xml
, y el comando que se ejecuta es en realidad
find -iname XYZ.xml
La razón por la que funciona si no hay archivos XML en el directorio actual es que los shells generalmente dejan comodines sin expandir si no coinciden con nada. En general, cada vez que quiera comodines para ser expandido en un programa que no sea el shell (por ejemplo, por find
, tar
, scp
, etc.) que necesita para citarlos por lo que la cáscara no tratará de ampliarlos en sí.
bash
, no de find
.
Debes citar tu argumento así:
find ./ -name '*.xml'
para que se pase a buscar en lugar de ser expandido por el shell, luego se pasa a buscar como la versión expandida.
*.xml
no coincide con nada en el directorio actual, se pasa literalmente, por lo que funciona en el otro caso. Muy útil respuesta.
Los comodines se expanden por el shell, no por el comando. find
es uno de los pocos comandos que realiza la coincidencia de comodines que es similar al shell, en su propio tiempo.
Cuando ejecuta ls *.xml
, primero el shell se expande *.xml
a la lista de archivos coincidentes, por ejemplo file1.xml
file2.xml
file3.xml
, y luego el shell llama ls
con la lista resultante de argumentos file1.xml
file2.xml
file3.xml
. Es por eso que ve la misma lista de nombres de archivo echo *.xml
, aunque echo
no sabe nada sobre los archivos y no le importa si sus argumentos son nombres de archivos.
Cuando corres find . -name "*.xml"
:
find
, .
, -name
, *.xml
en el que el *
se cita. Como *
se cita, es un personaje ordinario en lo que respecta al shell.find
con la lista especificada de argumentos: .
, -name
, *.xml
.find
busca archivos cuyo nombre coincida con el patrón *.xml
en cualquier directorio bajo el directorio actual.Cuando ejecuta find . -name *.xml
y no hay archivos que coincidan *.xml
:
find
, .
, -name
, *.xml
en el que el *
se que no se negocian.*.xml
contiene un carácter comodín sin comillas, el shell realiza la generación del nombre de archivo. Como no hay nombres de archivo coincidentes, el patrón permanece sin expandir.find
con la lista resultante de argumentos, que es .
, -name
, *.xml
.find
busca archivos cuyo nombre coincida con el patrón *.xml
en cualquier directorio bajo el directorio actual.Cuando ejecuta find . -name *.xml
y el directorio actual contiene file1.xml
, file2.xml
y file3.xml
:
find
, .
, -name
, *.xml
en el que el *
se que no se negocian.*.xml
contiene un carácter comodín sin comillas, el shell realiza la generación del nombre de archivo: *.xml
se reemplaza por la lista de nombres de archivo coincidentes.find
con la lista resultante de argumentos, que es .
, -name
, file1.xml
, file2.xml
, file3.xml
.find
se queja de un error de sintaxis cuando llega file2.xml
.Cuando ejecuta find . -name *.xml
y el directorio actual contiene un solo archivo coincidente file.xml
:
find
, .
, -name
, *.xml
en el que el *
se que no se negocian.*.xml
contiene un carácter comodín sin comillas, el shell realiza la generación del nombre de archivo: *.xml
se reemplaza por la lista de nombres de archivo coincidentes.find
con la lista resultante de argumentos, que es .
, -name
, file.xml
.find
ve un comando perfectamente válido, pero probablemente no sea lo que pretendía: find
se le dice que busque los archivos llamados file.xml
en cualquier directorio, no que busque ninguna coincidencia de archivos *.xml
.(La evaluación y expansión de Shell tiene muchas otras características. Solo mencioné las que son relevantes aquí).
(Lo que describo es el comportamiento predeterminado de los shells más comunes: sh, bash, dash, ksh, ... Algunos shells se pueden configurar para mostrar un error en lugar de ejecutar un comando con comodines sin expandir, o para expandir comodines no coincidentes a un vacío lista. Ninguno de esos ayudaría aquí.)
Esto funciona en Solaris 10:
find /directory-to-search/* -prune -name "*gz"
.xml
.
Por favor, inténtalo:
find ./ -name *.xml
*
siempre debe citarse o escaparon a pasarlo a encontrar.
man find
: Tenga en cuenta que debe citar patrones de forma habitual, de lo contrario, el shell expandirá los caracteres comodín en ellos.