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 $extension
lugar 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$extension
vacías.fuente
find
es recursivo por defecto. puede limitar las profundidades si lo desea (consulte la página de manual).Ejemplo: para buscar todos los
csv
archivos 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
grep
no es realmente necesario aquí.awk
tiene expresiones regulares y podría limitar su salida a valores que coincidan con un patrón.awk|grep
Es un antipatrón. Deja que awk haga el grepping.{
desaparecido despuésbrowsefolders ()
$in
debe ser$suffix
cut
te 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
find
solució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
find
comandos puede ser útil aquí, el shell en sí mismo proporciona opciones para cumplir este requisito sin herramientas de terceros. losbash
shell 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
extglob
que debe configurarse utilizando lashopt
opción que se muestra a continuación. Las opciones están habilitadas con el-s
soporte y deshabilitadas con la-u
bandera. Además, podría usar un par de opciones más, es decir,nullglob
en el que un globo incomparable se elimina por completo, reemplazado por un conjunto de cero palabras. Yglobstar
eso 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
*.csv
archivos en las rutas recursivasLa opción
**
es recurrir a través de las subcarpetas y*.csv
es 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
ls
con 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
find
comando). Por ejemplo, considere un caso de necesidad de obtener todos los archivos de imágenes recursivas, es decir, de extensiones*.gif
,*.png
y*.jpg
todo 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 ybash
shells, esta opción no sería la correcta.fuente
Para encontrar todos los
pom.xml
archivos en su directorio actual e imprimirlos, puede usar:fuente
fuente
fuente