linux - texto - Buscar recursivamente archivos con una extensión específica
linux buscar archivos ocultos (9)
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 terminal, dice:
[: 29: in: unexpected operator
(con $extension
lugar de ''in''
)
¿Qué está pasando aquí, dónde está el error? Pero este corsé
- Hay un
{
falta después debrowsefolders ()
- Todo
$in
debe ser$suffix
- La línea con el
cut
te lleva solo a la parte media defront.middle.extension
. Deberías leer tu manual de shell en${varname%%pattern}
y amigos.
Asumo que haces esto como un ejercicio en shell scripting, de lo contrario, la solución de find
ya propuesta es el camino a seguir.
Para verificar la sintaxis de shell correcta, sin ejecutar un script, use sh -n scriptname
.
Aunque el uso del comando de find
puede ser útil aquí, el propio shell proporciona opciones para lograr este requisito sin herramientas de terceros. El shell bash
proporciona una opción de soporte de glob extendido mediante la cual puede obtener los nombres de los archivos en rutas recursivas que coinciden con las extensiones que desea.
La opción extendida es extglob
que debe configurarse utilizando la opción shopt
como se muestra a continuación. Las opciones se habilitan con el soporte -s
y se deshabilitan con el indicador -u
. Además, podría usar un par de opciones más, es decir, nullglob
en el que un globo no emparejado se elimina completamente, reemplazado por un conjunto de cero palabras. Y globstar
que permite globstar
a través de todos los directorios.
shopt -s extglob nullglob globstar
Ahora todo lo que necesita hacer es formar la expresión glob para incluir los archivos de una cierta extensión que puede hacer de la siguiente manera. Usamos una matriz para rellenar los resultados globales porque cuando se citan correctamente y se expanden, los nombres de archivo con caracteres especiales permanecerán intactos y no se romperán debido a la división de palabras por parte del shell.
Por ejemplo, para listar todos los archivos *.csv
en las rutas recursivas
fileList=(**/*.csv)
La opción **
es repetir 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 haz
printf ''%s/n'' "${fileList[@]}"
Usar una matriz y realizar una expansión citada correcta es la forma correcta cuando se usa en scripts de shell, pero para uso interactivo, simplemente podría usar ls
con la expresión glob como
ls -1 -- **/*.csv
Esto podría muy bien expandirse para que coincida con múltiples archivos, es decir, el archivo que termina con una extensión múltiple (es decir, similar a agregar múltiples marcas en el comando de find
). 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 es
ls -1 -- **/+(*.jpg|*.gif|*.png)
Esto podría muy bien expandirse para tener resultados negativos también. Con la misma sintaxis, se podrían usar los resultados de los glob para excluir archivos de cierto tipo. Supongamos que desea excluir los nombres de archivo con las extensiones anteriores, podría hacer
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf ''%s/n'' "${excludeResults[@]}"
El constructo !()
Es una operación de negación para no incluir ninguna de las extensiones de archivo que figuran dentro y |
es un operador de alternancia tal como se utiliza 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 POSIX bourne shell 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 y bash
shells, esta opción no estaría bien.
La sintaxis que uso es un poco diferente de lo que sugirió @Matt:
find $directory -type f -name /*.in
(Es una pulsación menos).
Para encontrar todos los archivos pom.xml
en su directorio actual e imprimirlos, puede usar:
find . -name ''pom.xml'' -print
Sin usar find
:
du -a $directory | awk ''{print $2}'' | grep ''/.in$''
find $directory -type f -name "*.in"
es un poco más corto que todo eso (y más seguro: trata con espacios en blanco en nombres de archivos y nombres de directorios).
Su script probablemente está fallando para las entradas que no tienen una .
en su nombre, haciendo $extension
vacía.
find $directory -type f -name "*.in"|grep $substring
find {directory} -type f -name ''*.extension''
Ejemplo para encontrar todos los archivos csv en el directorio actual y sus subdirectorios
find . -type f -name ''*.csv''
for file in "${LOCATION_VAR}"/*.zip
do
echo "$file"
done