actualizar

actualizar

¿Cómo hacer un bucle recursivo a través de una ruta y obtener el último tar.gzarchivo creado en cada directorio?

Quiero ejecutar tar -tvf file.tar.gzel último archivo creado en cada directorio

Todos los tar.gzarchivos 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/baky 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 xargsque se ejecutará tar tvfen cada archivo.

Para solicitar entre cada tarball, agregue -pal xargscomando:

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 globales
    • N: se expande a nada si no hay ninguna coincidencia (nullglob)
    • /: solo directorios
    • om: 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.gzarchivos 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        

información relacionada