atualizar

atualizar

Como fazer um loop recursivo através de um caminho e obter o último tar.gzarquivo criado em cada diretório?

Quero executar tar -tvf file.tar.gzno último arquivo criado em cada diretório

Todos os tar.gzarquivos estão localizados no segundo nível de diretório. Portanto, a profundidade máxima do loop é 2

Este script imprimirá apenas cada diretório

cd $base_dir
find . -type d -printf '%f\n'

O diretório base é /var/www/bake todos os arquivos tar.gz estão localizados 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

atualizar

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

Responder1

Supondo que seus caminhos não contenham espaços ou novas linhas:

find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1

encontrará todos os tarballs, executará o snippet de shell fornecido em cada diretório que contém e filtrará o resultado para que apenas um resultado seja mantido para cada diretório.

Para visualizar o conteúdo dos tarballs, supondo que seus nomes de arquivos também não contenham espaços ou novas linhas:

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

substituirá o espaço que separa o caminho do nome do arquivo por “/”, e passará o resultado para xargso qual será executado tar tvfem cada arquivo.

Para solicitar entre cada tarball, adicione -pao 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

Responder2

Com zsh, no estilo típico somente de gravação:

for dir (*/*(N/)) (){(($#)) && tar tvf $1} $dir/*.tar.gz(Nom[1])
  • for var (values) cmd: forma mais curta defor var in values; do cmd; done
  • (N/), (Nom[1]): qualificadores globais
    • N: expande para nada se não houver correspondência (nullglob)
    • /: apenas diretórios
    • om: ordenar por hora de modificação (mais recente primeiro)
    • [1]: apenas primeira partida
  • (){...} args: funções anônimas com seus argumentos.

Com as ferramentas GNU (ainda sem fazer nenhuma suposição sobre quais bytes os nomes dos arquivos podem conter, mas atravessando diretórios ocultos e incluindo tar.gzarquivos ocultos) e qualquer shell do tipo Bourne, o equivalente poderia 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        

informação relacionada