Aquí hay una pequeña [pero completa] parte de mi fiestascript que encuentra y genera todos los archivos en mydir si tienen el prefijo de una matriz almacenada. Lo extraño que noto es que este script funciona perfectamente si elimino el "-maxdepth 1 -name" del script; de lo contrario, solo me da los archivos con el prefijo del primer elemento de la matriz.
Sería de gran ayuda si alguien me explicara esto. Lo siento de antemano si hay algo obviamente tonto que estoy haciendo. Soy relativamente nuevo en las secuencias de comandos.
#!/bin/sh
DIS_ARRAY=(A B C D)
echo "Array is : "
echo ${DIS_ARRAY[*]}
for dis in $DIS_ARRAY
do
IN_FILES=`find /mydir -maxdepth 1 -name "$dis*.xml"`
for file in $IN_FILES
do
echo $file
done
done
Salida:
/mydir/Abc.xml
/mydir/Ab.xml
/mydir/Ac.xml
Rendimiento esperado:
/mydir/Abc.xml
/mydir/Ab.xml
/mydir/Ac.xml
/mydir/Bc.xml
/mydir/Cb.xml
/mydir/Dc.xml
Respuestas
2 para la respuesta № 1El bucle está roto de cualquier manera. La razón por la cual
IN_FILES=`find mydir -maxdepth 1 -name "$dis*.xml"`
trabaja, mientras que
IN_FILES=`find mydir "$dis*.xml"`
no es porque en el primero, ha especificado -name
. En el segundo find
está enumerando todos los archivos en mydir
. Si cambia el segundo a
IN_FILES=`find mydir -name "$dis*.xml"`
verá que el bucle no funciona.
Como se menciona en los comentarios, la sintaxis que está utilizando actualmente $DIS_ARRAY
solo te dará el primer elemento de la matriz.
Intenta cambiar tu ciclo a esto:
for dis in "${DIS_ARRAY[@]}"
En este caso, las comillas dobles no son necesarias, por lo que puede hacer lo siguiente:
for dis in ${DIS_ARRAY[@]}
Las comillas son necesarias si su matriz contenía espacios, por ejemplo, si desea recorrer la matriz arr=( "a a" "b b" )
.
Aquí hay una prueba que muestra lo que está sucediendo:
#!/bin/sh
arr=("a a" "b b")
echo using "$arr"
for i in $arr; do echo $i; done
echo using "${arr[@]}"
for i in ${arr[@]}; do echo $i; done
echo using ""${arr[@]}""
for i in "${arr[@]}"; do echo $i; done
salida:
using $arr
a
a
using ${arr[@]}
a
a
b
b
using "${arr[@]}"
a a
b b
Mira esto pregunta relacionada para mas detalles.
1 para la respuesta № 2
La respuesta de @TomFenech resuelve su problema, pero permítame sugerirle otras mejoras:
#!/usr/bin/env bash
DIS_ARRAY=(A B C D)
echo "Array is : "
echo ${DIS_ARRAY[*]}
for dis in "${DIS_ARRAY[@]}"
do
for file in "/mydir/$dis"*.xml
do
if [ -f "$file" ]; then
echo "$file"
fi
done
done
- Tus referencias de línea shebang
sh
, pero tu pregunta está etiquetadabash
- a menos que necesite cumplimiento POSIX, use unbash
línea shebang para aprovechar todo esobash
tiene que ofrecer - Para hacer coincidir los archivos ubicados directamente en un directorio dado (es decir, si no necesita recorrer todo subárbol), use un globo (patrón de nombre de archivo) y confíe en la expansión del nombre de ruta como en mi código anterior - no es necesario
find
y la sustitución de comandos. - Tenga en cuenta que el carácter comodín.
*
no está entre comillas para garantizar la expansión del nombre de ruta. - Advertencia: si no se encuentran archivos coincidentes, el globo no se modifica (suponiendo que
nullglob
la opción de shell está desactivada, que es la opción predeterminada), por lo que el bucle se ingresa una vez, con un nombre de archivo no válido (el globo no expandido), de ahí el[ -f "$file" ]
condicional para asegurar que se encontró una coincidencia real (como un aparte: usando bashisms, podría usar[[ -f $file ]]
en lugar).