for i in $(ls);do
if [ $i = '*.java' ];then
echo "I do something with the file $i"
fi
done
Quiero recorrer cada archivo en la carpeta actual y verificar si coincide con una extensión específica. El código anterior no funciona, ¿sabes por qué?

for i in $(ls *.java); do echo "do something with file $i"; done?$icon la cadena literal "* .java"; La expansión del patrón no se realiza aquí.if [[ $i == *.java ]]; then.. (tenga en cuenta el doble [[]] sy sin comillas * .java).lsanalice - acepte la respuesta de @ chepnerRespuestas:
No se necesitan trucos sofisticados:
El guardia asegura que si no hay archivos coincidentes, el bucle saldrá sin intentar procesar un nombre de archivo inexistente
*.java. Enbash(o shells que admiten algo similar), puede usar lanullglobopción para simplemente ignorar una coincidencia fallida y no ingresar al cuerpo del bucle.fuente
for i in *.java *.cpp; do. Si tiene patrones extendidos habilitadosbashconshopt -s extglob, puede escribirfor i in *.@(java|cpp); do.shopt -s nullglobpara que un patrón que no coincida se expanda a la secuencia vacía en lugar de ser tratado literalmente.cdir a ese directorio antes de iniciar elforciclonullglobque se trate como una secuencia vacía o configurarfailglobpara que se trate como un error. (Si establece ambos,failglobtiene prioridad)la respuesta correcta es @ chepner's
sin embargo, aquí hay un pequeño truco para verificar si un nombre de archivo tiene extensiones determinadas:
fuente
extlugar de.java?Agregue subcarpetas de forma recursiva,
fuente
find . -name "*.java" -type f -exec echo \{\} \;evitar un análisis incorrecto de la salida defind"$i"dentro del ciclo.Bucle a través de todos los archivos que terminan con:
.img,.bin,.txtsufijo, e imprimir el nombre del archivo:O de manera recursiva (encontrar también en todos los subdirectorios):
fuente
Estoy de acuerdo con las otras respuestas con respecto a la forma correcta de recorrer los archivos. Sin embargo, el OP preguntó:
¡Si!
Un artículo excelente ¿Cuál es la diferencia entre prueba, [y [[?] Explica en detalle que, entre otras diferencias, no se puede usar
expression matchingopattern matchingdentro deltestcomando (que es la abreviatura de[)Entonces, esta es la razón por la que falla su script. Si el OP está interesado en una respuesta con la
[[sintaxis (que tiene la desventaja de no ser compatible con tantas plataformas como el[comando), me complacería editar mi respuesta para incluirla.EDITAR: ¡Cualquier sugerencia sobre cómo formatear los datos en la respuesta como una tabla sería útil!
fuente
como dice @chepner en su comentario, está comparando $ i con una cadena fija.
Para expandir y rectificar la situación, debe usar [[]] con el operador regex = ~
p.ej:
la expresión regular a la derecha de = ~ se prueba con el valor del operador de la mano izquierda y no se debe citar, (citado no generará errores, pero se comparará con una cadena fija y, por lo tanto, lo más probable es que falle "
pero la respuesta de @chepner anterior usando glob es un mecanismo mucho más eficiente.
fuente
extlugar de.java?if [[ $i == *.java ]]oif [[ $i == *.$ext ]]. Pero no analices lsEncontré esta solución bastante útil. Utiliza la
-oropción enfind:find . -name \*.tex -or -name "*.png" -or -name "*.pdf"Se encontrará los archivos con la extensión
tex,pngypdf.fuente