Quero baixar parte de um arquivo .tar.gz grande (199 GB) daqui . Para começar, usei o seguinte comando para listar todos os arquivos do arquivo .tar.gz:
wget -qO- https://www.cs.cornell.edu/projects/megadepth/dataset/Megadepth_v1/MegaDepth_v1.tar.gz | tar -tz
Em seguida, tentei baixar o conteúdo de uma pasta no .tar.gz usando o comando:
wget -qO- https://www.cs.cornell.edu/projects/megadepth/dataset/Megadepth_v1/MegaDepth_v1.tar.gz | tar -xz phoenix/S6/zl548/MegaDepth_v1/0000
No entanto, isso leva muito tempo porque o tar
comando pesquisa em profundidade e recursivamente em cada uma das pastas abaixo phoenix/S6/zl548/MegaDepth_v1
. Estou interessado apenas no conteúdo da pasta phoenix/S6/zl548/MegaDepth_v1/0000
. Existe uma maneira de baixar o conteúdo desta pasta sem pesquisar nas subpastas das outras pastas, como
phoenix/S6/zl548/MegaDepth_v1/0162
phoenix/S6/zl548/MegaDepth_v1/0001
phoenix/S6/zl548/MegaDepth_v1/0132
Em outras palavras, existe uma maneira mais rápida de baixar o conteúdo da pasta phoenix/S6/zl548/MegaDepth_v1/0000
?
Algumas referências para os comandos acima:
Como extrair arquivos específicos do tar.gz
Como baixar um arquivo e extraí-lo sem salvar o arquivo no disco?
tar
escreve um cabeçalho de arquivo, então o conteúdo do arquivo, então o próximo cabeçalho do arquivo, o próximo conteúdo do arquivo e assim por diante.Não há ordem associada às entradas e a única otimização que você pode fazer é pular o conteúdo de um arquivo, para chegar ao próximo cabeçalho, buscando-o diretamente. Para isso, você precisa ter um arquivo pesquisável.
Mas o seu
.gz
está compactado, então você não tem uma maneira confiável de pular para a próxima entrada, o que significa que você terá que ler (baixar) o arquivo inteiro para obter o conteúdo. Essa é a resposta: não, você não pode evitar ler/baixar o arquivo inteiro.Então, já que você terá que baixá-lo completamente de qualquer maneira, você pode fazer isso uma vez e depois resolver tudo no sistema de arquivos local.
Bem, na verdade não. Ele não pesquisa e, em vez disso, apenas lê o arquivo, examinando todos os arquivos que encontra para ver se eles correspondem ao que deseja. (Você obtém o comportamento de profundidade, já que essa é a ordem natural para percorrer uma árvore de diretórios e, portanto, a ordem em que os arquivos foram adicionados ao arquivo.)
Isso ocorre porque os arquivos tar não têm índices, eles não são pesquisáveis. O nome "tar" significa "arquivo de fita", e o modo usual de usar fitas é apenas ler ou escrever um único fluxo, sem procurar. O formato foi feito para esse contexto e pode não ser o melhor para o seu caso de uso.
Não consigo encontrar uma boa citação sobre isso, mas é mencionado em algumas respostas no site e na Wikipedia .
Toda vez que você estava executando
wget
, você estava tentando baixar o arquivo tar inteiro! Você já deve ter baixado o "conteúdo inicial" várias vezes e o descartado enviando a saída para stdout!Em vez disso, a maneira "mais rápida" seria baixá-lo uma vez para ./MegaDepth_v1.tar.gz em seu diretório atual e descompactá-lo lá.
Depois de ter os arquivos necessários, você pode excluir o arquivo tar baixado.
ATUALIZAÇÃO: O arquivo original parece ter cerca de 200 GB de tamanho. O download em si ocupará muito tempo e espaço. A extração levará então mais tempo. Nenhuma vitória , neste caso!
Você pode ter que entrar em contato com a equipe do MegaDepth e pedir que eles forneçam acesso individual ao diretório, caso contrário, será sempre lento.
Aqui,
wget
não pode pular conteúdo indesejado e sempre baixará todo o arquivo tar do começo ao fim. Além disso, (como mencionado na resposta pelo usuário ilkkach )tar
não pode pular (ou procurar) o fluxo stdout.Análise
Concordo com outras respostas dizendo que não há como
tar
buscar o arquivo compactado. Para encontrar o(s) arquivo(s) que você procura, a ferramenta precisa processar o arquivo desde o início e não pular nada.No entanto, com o GNU
tar
, você não precisa necessariamente processá-lo até o fim. Considere este cenário ao criar um arquivo:( fonte )
Isso significa que, ao extrair um arquivo específico,
tar
continua processando o arquivo mesmo depois de extrair o arquivo, pois talvez outra cópia esteja posteriormente no arquivo.Mas então:
(ibid.)
Se você tiver certeza de que o arquivo que você está procurando ocorre exatamente uma vez no arquivo, use
tar --occurrence
etar
parará depois de extrair o arquivo. Então vocêwget
vai abortar devido aSIGPIPE
, não vai baixar o resto do arquivo em vão.Utilidade limitada
Observe que isso não é realmente útil no seu caso exato porque
phoenix/S6/zl548/MegaDepth_v1/0000
é um diretório (certo?). Ao extrair o diretório com--occurrence
,tar
não parará mais cedo, a menos que encontre outra entrada para o próprio diretório . A razão é: sempre pode haver um únicophoenix/S6/zl548/MegaDepth_v1/0000/foo
no final do arquivo. Antestar
de chegar ao fim, não se pode ter certeza de que o diretório com todo o seu conteúdo está completo.Ainda assim, se você estivesse atrás de um ou poucos não-diretórios , se conhecesse o(s) caminho(s) e se soubesse que há exatamente uma instância de cada um no arquivo,
--occurrence
permitiria baixar o mínimo necessário do arquivo. Se você tiver sorte e os arquivos estiverem próximos do início do arquivo,--occurrence
isso fará uma diferença significativa.Provavelmente esta resposta não vai te ajudar muito. É para usuários que podem fornecer uma lista de não diretórios .
A não ser que…
Se você salvou a saída de
wget -qO- … | tar -tz
(quando você provavelmente baixou e processou todo o arquivo e o jogou fora), agora você poderá fornecer uma lista de não-diretórios (possivelmente usando--files-from=
ou--verbatim-files-from
; especialmente útil se a lista for muito longa para uma única linha de comando). Neste caso--occurrence
pode funcionar para você. Além disso, a saída salva detar -t
permitiria que você confirmasse que cada não-diretório que você procura ocorre exatamente uma vez no arquivo, para que você saiba--occurrence
que não perderá uma versão atualizada.O acima assume
MegaDepth_v1.tar.gz
no servidor não muda. Em geral (se o arquivo pode ter mudado) sua saída salvatar -t
pode não ser mais válida.Vamos supor que você possa criar uma lista de não-diretórios para extrair. A lista não deve especificar nenhum diretório explicitamente, caso contrário
--occurrence
não o ajudará. Aindatar
criará diretórios necessários, mas apenas com o objetivo de colocar não diretórios neles, não porque realmente extrairá os diretórios do arquivo. Em outras palavras: os membros do arquivo para os próprios diretórios não importam. Isso significa que os diretórios serão criados, mas opções como--preserve-permissions
não se aplicarão a eles.Prova de conceito
Eu usei seu primeiro comando (aquele com
tar -t
) e descobri quephoenix/S6/zl548/MegaDepth_v1/0162/dense0/depths/16384199365_2b34b42cf4_b.h5
é um não-diretório próximo ao início do arquivo. Este encanamento:extrai o arquivo e continua (posso Ctrl+ c); mas este:
extrai o arquivo e termina automaticamente.