
¿Cómo hacer un bucle recursivo a través de una ruta y obtener el último tar.gz
archivo creado en cada directorio?
Quiero ejecutar tar -tvf file.tar.gz
el último archivo creado en cada directorio
Todos los tar.gz
archivos están ubicados en el segundo nivel de directorio. Entonces, la profundidad máxima del bucle es 2
Este script solo imprimirá cada directorio
cd $base_dir
find . -type d -printf '%f\n'
El directorio base es /var/www/bak
y todos los archivos tar.gz están ubicados como
/var/www/bak/site1/www/file.tar.gz
/var/www/bak/site1/db/file.tar.gz
/var/www/bak/site2/www/file.tar.gz
/var/www/bak/site2/db/file.tar.gz
actualizar
find_tarballs (){
cd $base_dir
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD}/\"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1
}
filesize (){
ls -lh $1 | awk -F " " {'print $5'}
}
output="$(find_tarballs)"
set -- $output
shift
for tarball; do
echo "$tarball"
if [ ${tarball##*.} = 'gz' ]; then
list="$(tar -tzf $tarball)"
echo "Filesize: $(filesize $tarball), Files: $(echo "$list" | wc -l)\n"
echo 'Press ENTER to list files...'
read key
echo "$list"
else
echo "Filesize: $(filesize $tarball)"
fi
echo ''
done
Respuesta1
Suponiendo que sus rutas no contengan espacios ni nuevas líneas:
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1
encontrará todos los archivos comprimidos, ejecutará el fragmento de shell proporcionado en cada directorio que lo contenga y filtrará el resultado para que solo se mantenga un resultado para cada directorio.
Para ver el contenido de los archivos tar, suponiendo que sus nombres de archivo tampoco contengan espacios ni nuevas líneas:
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1 | tr ' ' / | xargs -n 1 tar tvf
Reemplazará el espacio que separa la ruta del nombre del archivo por "/" y pasará el resultado al xargs
que se ejecutará tar tvf
en cada archivo.
Para solicitar entre cada tarball, agregue -p
al xargs
comando:
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1 | tr ' ' / | xargs -p -n 1 tar tvf
Respuesta2
Con zsh
, en la forma típica de solo escritura:
for dir (*/*(N/)) (){(($#)) && tar tvf $1} $dir/*.tar.gz(Nom[1])
for var (values) cmd
: forma más corta defor var in values; do cmd; done
(N/)
,(Nom[1])
: clasificatorios globalesN
: se expande a nada si no hay ninguna coincidencia (nullglob)/
: solo directoriosom
: ordenar por hora de modificación (el más nuevo primero)[1]
: solo primer partido
(){...} args
: funciones anónimas con sus argumentos.
Con las herramientas GNU (aún sin asumir qué bytes pueden contener los nombres de los archivos, pero atravesando directorios ocultos e incluyendo tar.gz
archivos ocultos) y cualquier shell tipo Bourne, el equivalente podría ser:
LC_ALL=C find . -mindepth 3 -maxdepth 3 -name '*.tar.gz' -printf '%T@:%p\0' |
sort -zn | LC_ALL=C awk -v RS='\0' -v ORS='\0' '
{match($0, ":((.*)/.*)", parts); newest[parts[2]] = parts[1]}
END {for (dir in newest) print newest[dir]}' |
xargs -r0n1 tar tvf