Descompactando usando tar: --exclua muito ganancioso: como excluir somente o arquivo de nível de raiz?

2

Eu estou em um Mac, El Capitan.

Minha estrutura de arquivos zip:

README.md
source/README.md

Eu não consigo encontrar --exclude do nível de raiz README.md sem excluir também o do diretório source .

Eu tenho tentado variações de coisas, como:

# Doesn’t exclude anything:
tar -xf master.zip --strip-components 1 --exclude=/README.md
tar -xf master.zip --strip-components 1 --exclude=/{install.sh,README.md}

# Excludes both files:
tar -xf master.zip --strip-components 1 --exclude=./README.md
tar -xf master.zip --strip-components 1 --exclude={install.sh,README.md}
tar -xf master.zip --strip-components 1 --exclude=./{install.sh,README.md}

Pergunta:

Como posso excluir somente o nível de raiz README.md

    
por mhulse 27.03.2016 / 06:17

3 respostas

3

Na verdade, o tar pode excluir arquivos com --anchored

patterns match file name start

Mas então você tem que escrever todo o caminho do arquivo (que também muda com cd ):

$ cd /where/source/lives
$ tar -cf master.zip --anchored --exclude={source/install.sh,README.md} -- *

Se você precisar de alguma flexibilidade, use o find.
A lista de arquivos a serem compactados pode ser criada com este comando,
o ! -name README.md rejeita o arquivo README.md de base:

$ path="/path/to/files"
$ find "$path/" ! -path  "$path"/README.md -print

Cuidado com as barras / , elas são importantes. Se isso contiver a lista correta de arquivos a serem compactados, basta injetar isso em tar (adicione 0 a -print e crie o comando tar ):

find "$path/" ! -path  "$path"/README.md -print0 |
tar --no-recursion --null -T- --exclude=install.sh -v -cf master.zip

Observe que tar está usando a opção --null para corresponder à -print0 de find .

Como find está fornecendo toda a recursão necessária, use a opção --no-recursion do tar.

Além disso, o arquivo install.sh ainda está sendo excluído em tar (que também pode ter sido removido com find , mas isso é apenas uma preferência pessoal).

Na produção, remova a opção -v para obter um comando tar menos detalhado.

Para descomprimir (em vez de comprimir como acima), use isto:

tar -xf master.zip --anchored --exclude={source/install.sh,README.md}

Ou, se você usar a segunda opção para criar o arquivo compactado, os arquivos excluídos não estarão dentro de master.zip e tudo o que você precisa fazer é:

tar -xf master.zip    
    
por 27.03.2016 / 09:05
2

Alguém pode aparecer com uma resposta melhor, mas se a opção --exclude do tar não estiver cortando, você pode usar find para gerar uma lista de arquivos e depois alimentar esse tar . Por exemplo:

find * -path README.md -prune -o -print | 
tar --no-recursion -cf /tmp/data.tar -T-

Isso imprime uma lista de todos os arquivos (e diretórios) que não são do nível superior README.md e, em seguida, os alimenta para tar , que lê sua lista de arquivos de stdin (usando -T- ) . O --no-recursion sinalizador é necessário porque senão tar incluirá automaticamente todos os arquivos nos diretórios, o que você não deseja porque esses arquivos também serão produzidos por find e você acabaria com vários arquivos no arquivo com o mesmo nome.

Uma versão mais robusta pode parecer:

find * -path README.md -prune -o -print0 | 
tar --no-recursion -cf /tmp/data.tar --null -T-

Aqui, o -print0 to find e o --null to tar significam que os nomes de arquivos serão separados por caracteres ASCII NUL em vez de espaços em branco, o que significa que o pipeline manipulará nomes de arquivos contendo espaços.

    
por 27.03.2016 / 06:28
1

O utilitário pax tem um recurso de exclusão que é um pouco mais amplo que o tar do BSD. Sua opção -s permite transformar nomes à medida que são armazenados ou extraídos e, se um nome for transformado em uma string vazia, esse arquivo será excluído.

(o BSD tem uma opção -s um pouco semelhante, mas seguindo a documentação, ele não parece ter o recurso de exclusão no vazio.)

zcat foo.tar.gz | pax -r -pe -s'!^README\.md$!!' -s'!^\./README\.md$!!'

Note que estou assumindo um arquivo tar (possivelmente compactado). Se você tiver um arquivo zip, use unzip em vez disso.

unzip foo.zip -x 'README.md'
    
por 28.03.2016 / 00:06

Tags