Tar uma lista de arquivos sem sua estrutura de diretórios

1

Digamos que eu faça isso:

tar cvf allfiles.tar $(<mylist.txt)

e mylist.txt contém isto:

/tmp/lib1
/tmp/path2/lib2
/path3/lib3

Como tar os arquivos para que o tarball contenha apenas

lib1
lib2
lib3

sem estrutura de diretórios?

As opções -C de --directory geralmente são recomendadas ( ref , ref ), mas existem vários diretórios, então isso não funciona. Além disso, --xform parece exigir um padrão fixo ( ref ) que não temos.

    
por Drakes 21.10.2016 / 07:07

2 respostas

4

O argumento --xform usa qualquer número de expressões substitutas de sed , que são muito poderosas. No seu caso, use um padrão que corresponda a tudo até o último / e substitua-o por nada:

tar cvf allfiles.tar --xform='s|.*/||' $(<mylist.txt)

Adicione --show-transformed-names para ver os novos nomes.

Note que esta substituição se aplica a todos os nomes de arquivos, não apenas àqueles dados na linha de comando, por exemplo, se você tiver um arquivo /a/b/c e sua lista especificar /a , o nome final do arquivo é apenas c , não b/c . Você sempre pode ser mais explícito e fornecer uma lista exata de substituições, por exemplo, no seu caso

--xform='s|^tmp/path2/||;s|^tmp/||;s|^path3/||'

Note que o / inicial será removido pelo tar (a menos que você use -P ), então as expressões acima estão faltando. Além disso, a lista de diretórios deve ser classificada para que a correspondência mais longa seja feita primeiro. Caso contrário, tmp/path2/ não corresponderá, pois tmp/ já foi removido. Mas você pode automatizar a criação desta lista, por exemplo:

--xform="$(sed <mylist.txt 's|[^/]*$||; s|^/||; s:.*:s|^&||;:' | sort | tr -d '\n')"
    
por 21.10.2016 / 09:40
2

Com o GNU tar , você pode usar -C quando e quantas vezes quiser, com efeito imediato.

$ tree
.
├── 1
│   └── aaa
├── 2
│   └── bbb
└── 3
    └── ccc



# Caveat: the directory change is always relative to directory tar is using *at
# that time*, so the following doesn't work:
$ tar -cf foo.tar -C 1 aaa -C 2 bbb -C 3 ccc  
tar: 2: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

$ tar -cf foo.tar -C 1 aaa -C ../2 bbb -C ../3 ccc

$ tar tf foo.tar
aaa
bbb
ccc


# You can avoid the special case for the first directory by always specifying
# an absolute path:
$ tar -cf foo.tar -C $(pwd)/1 aaa -C $(pwd)/2 bbb -C $(pwd)/3 ccc



# Now let's create that automatically from your file:
$ cat mylist.txt
/tmp/1/aaa
/tmp/2/bbb
/tmp/3/ccc

$ while read -r line; do printf '-C %s %s ' $(dirname "$line") $(basename "$line") ; done < mylist.txt
-C /tmp/1 aaa -C /tmp/2 bbb -C /tmp/3 ccc 

# That looks about right. Let's use it in our tar command:
$ tar -cvf foo.tar $(while read -r line; do printf '-C %s %s ' $(dirname "$line") $(basename "$line") ; done < mylist.txt)
aaa
bbb
ccc
    
por 21.10.2016 / 08:39