Estoy tratando de encontrar todos los archivos con una extensión específica en un directorio y sus subdirectorios con mi bash (última versión de Ubuntu LTS).
Esto es lo que está escrito en un archivo de script:
#!/bin/bash
directory="/home/flip/Desktop"
suffix="in"
browsefolders ()
for i in "$1"/*;
do
echo "dir :$directory"
echo "filename: $i"
# echo ${i#*.}
extension=`echo "$i" | cut -d'.' -f2`
echo "Erweiterung $extension"
if [ -f "$i" ]; then
if [ $extension == $suffix ]; then
echo "$i ends with $in"
else
echo "$i does NOT end with $in"
fi
elif [ -d "$i" ]; then
browsefolders "$i"
fi
done
}
browsefolders "$directory"
Desafortunadamente, cuando comienzo este script en la terminal, dice:
[: 29: in: unexpected operator
(con en $extensionlugar de 'in')
¿Qué está pasando aquí, dónde está el error? Pero este corsé rizado

Respuestas:
es un poco más corto que todo eso (y más seguro: trata con espacios en blanco en los nombres de archivos y directorios).
Probablemente, su secuencia de comandos esté fallando para las entradas que no tienen un
.nombre, quedando$extensionvacías.fuente
findes recursivo por defecto. puede limitar las profundidades si lo desea (consulte la página de manual).Ejemplo: para buscar todos los
csvarchivos en el directorio actual y sus subdirectorios, use:fuente
La sintaxis que uso es un poco diferente de lo que sugirió @Matt:
(Es una pulsación menos).
fuente
Sin usar
find:fuente
grepno es realmente necesario aquí.awktiene expresiones regulares y podría limitar su salida a valores que coincidan con un patrón.awk|grepEs un antipatrón. Deja que awk haga el grepping.{desaparecido despuésbrowsefolders ()$indebe ser$suffixcutte lleva solo a la parte mediafront.middle.extension. Debes leer tu manual de shell${varname%%pattern}y amigos.Supongo que haces esto como un ejercicio de scripting de shell, de lo contrario, la
findsolución ya propuesta es el camino a seguir.Para verificar la sintaxis de shell adecuada, sin ejecutar un script, use
sh -n scriptname.fuente
fuente
Aunque el uso de
findcomandos puede ser útil aquí, el shell en sí mismo proporciona opciones para cumplir este requisito sin herramientas de terceros. losbashshell proporciona una opción de soporte global extendido mediante la cual puede obtener los nombres de archivo en rutas recursivas que coincidan con las extensiones que desee.La opción extendida es la
extglobque debe configurarse utilizando lashoptopción que se muestra a continuación. Las opciones están habilitadas con el-ssoporte y deshabilitadas con la-ubandera. Además, podría usar un par de opciones más, es decir,nullgloben el que un globo incomparable se elimina por completo, reemplazado por un conjunto de cero palabras. Yglobstareso permite recurrir a través de todos los directorios.Ahora todo lo que necesita hacer es formar la expresión global para incluir los archivos de una determinada extensión, que puede hacer como se muestra a continuación. Usamos una matriz para llenar los resultados globales porque cuando se citan correctamente y se expanden, los nombres de archivo con caracteres especiales permanecerían intactos y no se romperían debido a la división de palabras por el shell.
Por ejemplo, para enumerar todos los
*.csvarchivos en las rutas recursivasLa opción
**es recurrir a través de las subcarpetas y*.csves una expansión global para incluir cualquier archivo de las extensiones mencionadas. Ahora para imprimir los archivos reales, solo hazUsar una matriz y hacer una expansión entre comillas adecuada es la forma correcta cuando se usa en scripts de shell, pero para uso interactivo, simplemente puede usar
lscon la expresión global comoEsto podría muy bien expandirse para que coincida con varios archivos, es decir, el archivo que termina con una extensión múltiple (es decir, similar a agregar varios indicadores en el
findcomando). Por ejemplo, considere un caso de necesidad de obtener todos los archivos de imágenes recursivas, es decir, de extensiones*.gif,*.pngy*.jpgtodo lo que necesita esEsto podría muy bien expandirse para tener resultados negativos también. Con la misma sintaxis, uno podría usar los resultados del globo para excluir archivos de cierto tipo. Suponga que desea excluir los nombres de archivo con las extensiones anteriores, podría hacer
La construcción
!()es una operación negativa para no incluir ninguna de las extensiones de archivo enumeradas en el interior y|es un operador de alternancia tal como se usa en la biblioteca de Expresiones regulares extendidas para hacer una coincidencia OR de los globos.Tenga en cuenta que este soporte global extendido no está disponible en el shell POSIX bourne y es puramente específico de las versiones recientes de
bash. Entonces, si está considerando la portabilidad de los scripts que se ejecutan en POSIX ybashshells, esta opción no sería la correcta.fuente
Para encontrar todos los
pom.xmlarchivos en su directorio actual e imprimirlos, puede usar:fuente
fuente
fuente