procura recursiva e imprime o arquivo tar.gz mais recente em cada diretório

1

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

Eu quero executar tar -tvf file.tar.gz no último arquivo criado em cada diretório

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

Este script só imprime cada diretório

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

O diretório base é /var/www/bak e 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
    
por clarkk 28.04.2017 / 16:51

2 respostas

2

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 fragmento de shell fornecido em cada diretório contido 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 arquivo 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 xargs , que executará tar tvf em cada arquivo.

Para solicitar entre cada tarball, adicione -p ao comando xargs :

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
    
por 28.04.2017 / 17:00
2

Com zsh , na forma típica de gravação:

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

Com as ferramentas GNU (ainda não fazendo suposições sobre o que os nomes de arquivos de bytes podem conter, mas percorrendo diretórios ocultos e incluindo arquivos tar.gz ocultos) e qualquer shell parecido com o Bourne, o equivalente poderia ser:

LC_ALL=C find . -mindepth 3 -maxdepth 3 -name '*.tar.gz' -printf '%T@:%p
for dir (*/*(N/)) (){(($#)) && tar tvf $1} $dir/*.tar.gz(Nom[1])
' | sort -zn | LC_ALL=C awk -v RS='
LC_ALL=C find . -mindepth 3 -maxdepth 3 -name '*.tar.gz' -printf '%T@:%p%pre%' |
  sort -zn | LC_ALL=C awk -v RS='%pre%' -v ORS='%pre%' '
    {match($0, ":((.*)/.*)", parts); newest[parts[2]] = parts[1]}
    END {for (dir in newest) print newest[dir]}' |
    xargs -r0n1 tar tvf        
' -v ORS='%pre%' ' {match($0, ":((.*)/.*)", parts); newest[parts[2]] = parts[1]} END {for (dir in newest) print newest[dir]}' | xargs -r0n1 tar tvf
    
por 29.04.2017 / 00:34

Tags