Encontre o nome do diretório extraído do arquivo tar

3

Eu tenho um projeto onde estou baixando e compilando um monte de arquivos. As suposições que posso fazer sobre esses arquivos são:

  • só haverá um diretório de nível superior
  • o nome da pasta não corresponde necessariamente ao nome do arquivo tar.xz / gz (em outras palavras, algo-1.3.5a.tar.gz pode extrair para uma pasta chamada algo-1.3.5)

Para diminuir a quantidade de digitação que eu tenho que fazer, eu escrevi um pequeno script, que entre outras coisas é o seguinte:

  • extrai o arquivo tar.xz / gz
  • cds no diretório

Meu hack atual é fazer algo assim:

test1=$(tar -axvf something-1.3.5a.tar.gz)

cd $(echo $test1 | cut -f1 -d" ")

Basicamente, o que isto faz é capturar a saída da extração, e pega a primeira linha (que é o diretório de nível superior) e depois cds nela.

Então, minha pergunta é: existe uma maneira mais limpa / melhor de fazer isso?

    
por bash_noob-3.14.tar.gz 14.09.2015 / 03:15

2 respostas

5

#!/bin/sh
Dir_name='tar -tzf something-1.3.5a.tar.gz | head -1 | cut -f1 -d"/"'
echo $Dir_name

tar options details,
-t, --list 
-z, --gzip, --ungzip               filter the archive through gzip
-f, --force-local              archive file is local even if has a colon

Aqui, estamos obtendo a lista de arquivos no tar e pegando a primeira linha usando head -1 cmd, extraindo o primeiro campo usando o cmd cortado.

    
por 02.12.2015 / 10:10
0

Se você tiver um diretório superior e nada, você pode simplesmente lembrar quais diretórios existem antes de executar o tar, e ver o que você tem depois disso, assumindo que ninguém mais tenha alterado esse diretório.

 # ksh terminology: set -A BEFORE .*/ */
 BEFORE=(.*/ */)
 tar -xf blah blah blah
 AFTER=(.*/ */)
 # We can make it O(n), since glob outputs can be assumed to be sorted.
 # Do it.
 for (( i = 0; i < "${#BEFORE[@]}"; i++ )); do
    [ "${BEFORE[i]}" == "${AFTER[i]}" ] || break
 done
 cd "${AFTER[i]}"

Isso deve funcionar com todos os shells que tem aritmética for , arrays começando com um índice zero e com ${#arr[@]} para acessar a contagem de membros do array.

Na verdade, existe um problema, pois */ pode se expandir para literalmente */ quando não há correspondência. Em bash (assumindo que você está usando bash por causa de sua tag), você pode definir shopt -s nullglob para isso.

Usar */ restringe os itens globbed aos diretórios, assim você não se preocupará com arquivos - Arquivos extras ainda fazem dele apenas um diretório:)

    
por 15.09.2015 / 06:59