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
?$i
con 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).ls
analice - 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 lanullglob
opció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 habilitadosbash
conshopt -s extglob
, puede escribirfor i in *.@(java|cpp); do
.shopt -s nullglob
para que un patrón que no coincida se expanda a la secuencia vacía en lugar de ser tratado literalmente.cd
ir a ese directorio antes de iniciar elfor
ciclonullglob
que se trate como una secuencia vacía o configurarfailglob
para que se trate como un error. (Si establece ambos,failglob
tiene 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
ext
lugar 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
,.txt
sufijo, 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 matching
opattern matching
dentro deltest
comando (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
ext
lugar de.java
?if [[ $i == *.java ]]
oif [[ $i == *.$ext ]]
. Pero no analices lsEncontré esta solución bastante útil. Utiliza la
-or
opción enfind
:find . -name \*.tex -or -name "*.png" -or -name "*.pdf"
Se encontrará los archivos con la extensión
tex
,png
ypdf
.fuente