Como posso achatar arquivos .tar.gz aninhados?

2

Eu tenho um monte de arquivos .tar.gz em caminhos diferentes. Eu gostaria de criar um novo arquivo .tar.gz em algum ancestral comum deles e não quero que ele seja composto de arquivos .tar.gz aninhados. Como posso facilmente achatar o arquivo depois de criado?

    
por dromodel 25.02.2014 / 02:27

3 respostas

2

Aqui está um script bash para extrair recursivamente um arquivo tar , remover os arquivos aninhados originais e criar um novo arquivo. Leva dois argumentos - primeiro é o arquivo original, segundo é o nome do novo arquivo. Ambos devem ser caminhos relativos. Isto irá extrair o diretório do arquivo, mas se recusará a atacar os arquivos existentes (para isso, remova a opção -k do comando tar ). Outra abordagem para evitar a invasão seria criar um novo diretório para cada arquivo e extraí-lo lá.

#!/bin/bash

archive="$1"
new_archive="$2"

# common extensions, full list at
# http://www.gnu.org/software/tar/manual/html_section/Compression.html#auto_002dcompress
match_archives='.*\.\(tar\|\(tar\.\(gz\|bz2\|xz\)\)\|\(tgz\|tbz\)\)$'

recursive_extract ()
{
  retval=0

  while read -rd '' path
  do
    if [ -e "$path" ]
    then
        nested_archive=${path##*/}
        if cd "${path%/*}" && tar -xakf "$nested_archive" 
        then
            rm "$nested_archive"
            find . -regex "$match_archives" -print0 | recursive_extract
            retval=$?
        else
            echo "Error extracting $nested_archive, not removing"
            retval=1
        fi
    fi
  done

  return $retval
}

tmpdir=$(mktemp -d) 
cd "$tmpdir"

tar -xaf "$OLDPWD/$archive" &&
  find . -regex "$match_archives" -print0 | recursive_extract &&
  tar -caf "$OLDPWD/$new_archive" * &&
  cd -- "$OLDPWD" &&
  rm -rf $tmpdir ||
  echo "Errors, please review $tmpdir"

Observe que, se a extração resultar em um erro, é possível que o acima tente extrair o mesmo arquivo várias vezes.

    
por 25.02.2014 / 13:38
1

Você pode fazer o seguinte:

extrair arquivo

$ mkdir tmpdir
$ tar xfz a.tar.gz -C tmpdir/

achatar para newdir

$ mkdir newdir
$ find tmpdir/ -type f -exec mv -i {} newdir/. \;

re-comprima o arquivo

$ tar zcvf somenew.tar.gz newdir/
    
por 25.02.2014 / 05:09
0

Com bsdtar e zsh :

set -o extendedglob # for (#i) case insensitive globbing operator
files=(**/*.(#i)(zip|7z|iso|cpio|a|ar|tar(|.[gx]z|.bz2)|t[bgx]z|tbz2)(D.))
bsdtar zcf result.tar.gz @$^files

(incluindo todos os formatos de arquivo suportados por bsdtar / libarchive ).

Note que ele não recursivamente extrai arquivos. Se houver um arquivo a.tar.gz que contenha a1.txt e a1.tar.gz e b.tar.gz com b1.txt e b1.tar.gz , result.tar.gz conterá a1.txt , a1.tar.gz , b1.txt , b1.tar.gz .

Ele também incluirá arquivos com o mesmo caminho várias vezes.

Extrair os arquivos em um diretório e arquivar novamente o diretório resultante tem alguns problemas:

  • se você não for root , não poderá preservar as propriedades do arquivo e alguns atributos.
  • A propriedade
  • é armazenada em tar archives como o nome do usuário e os IDs do usuário. Ao extrair, tar irá, por padrão, tentar usar os nomes de usuários e extrair com o uid correspondente no sistema de extração (e se não houver nenhum usuário com esse nome, use o uid). Então, ao recriar o arquivo, os uids podem ser diferentes, mesmo se executados como root.
  • Dependendo do tipo de sistema de arquivos para o qual você está extraindo o arquivo, alguns atributos de arquivo, como ACLs ou atributos estendidos, podem ser perdidos.
  • Se o diretório para o qual você está extraindo os arquivos tiver o bit sgid ou ACLs padrão, eles também poderão afetar os arquivos no archive.
por 21.11.2017 / 13:20

Tags