Eu tenho uma pasta com cerca de 20 mil arquivos. Os arquivos são nomeados de acordo com o padrão xy_{\d1,5}_{\d4}\.abc
, por exemplo xy_12345_1234.abc
. Eu queria comprimir os primeiros 10K deles usando este comando:
ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz
no entanto, o arquivo resultante tinha apenas cerca de 2K arquivos dentro.
ls | sort -n -k1.4,1.9 | head -n10000 | wc -l
no entanto retorna 10000, conforme o esperado.
Parece-me que estou entendendo mal algo básico aqui ...
Estou usando o zsh 5.0.2 no Linux Mint 17.1, o GNU tar 1.27.1
EDITAR:
forjar como sugerido por @Archemar soa muito plausível, com o fork mais recente sobrescrevendo o arquivo resultante - o arquivo contém a 'cauda' dos arquivos - 7773 para 9999 .
Resultado de xargs --show-limit
:
Your environment variables take up 3973 bytes
POSIX upper limit on argument length (this system): 2091131
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2087158
Size of command buffer we are actually using: 131072
substituindo -c
com -r
ou -u
não funcionou no meu caso. A mensagem de erro foi tar: Cannot update compressed archives
usando ambos -r
e -u
é inválido e falha com tar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option
substituindo -c
com -a
parece ser inválido também e falha com o mesmo tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
embora eu não reconheça o problema azf
e Acdtrux
parecem disjuntos para mim.
EDIT 2:
-T parece um bom caminho, eu também encontrei um exemplo Aqui .
No entanto, quando tento
ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T -
eu recebo tar: option requires an argument -- 'T'
bem, talvez os nomes dos arquivos não alcancem o alcatrão? Mas parece que eles, porque quando eu executo
ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T -
eu recebo tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab
Cannot stat: File name too long
Então, por que o tar não está vendo os nomes dos arquivos?
ls
find
, que tem um-print0
opção para usar um byte nulo como o delimitador em vez de uma nova linha.sort
pode lidar com isso com o-z
bandeira.head
, infelizmente não manipula entender delimitadores de bytes nulos, mas esta resposta tem uma solução usandotr
trocar\n
e\0
antes e depoishead
.tar
tem--null -T -
ler nomes de arquivos delimitados por nulo destdin
.Respostas:
você atingiu o limite de xargs?
experimentar :
.tgz
Arquivotar czf xy_0_10000.tar.gz /hello/world
-czf
por-Azf
quando o xarg atingir seu limite, ele irá bifurcar o comando, então o comando que você executou foi
como cada tar substituir o anterior, você deve estar ficando apenas por último
tar c
corre.Editar:
1)
de acordo como acréscimo é feito por (qualquer um)man tar
no Ubuntu-a
e -r parece equivalente-A, --catenate, --concatenate
2)
zip
(nãogzip
) pode ser usado para adicionar arquivo, talvez uma opção gzip irá fazer o truque. (usar| xargs zip -qr xy_0_0000.zip
, isso resultará em um arquivo zip, não no .tar.gz, no entanto)3) usar a solução do @ rsanchez
É importante adicionar a opção ao tar de forma adequada, tente
Onde -
-T -
significa a opção de uso-T
E use-
como argumento para-T
(você poderia gerar uma lista de arquivos em/tmp/foo.lst
, então use-T /tmp/foo.lst
)fonte
a (add)
para adicionar os arquivos ao arquivo tar. Então, você pode abrir o tar e remover a pasta (usando 7zip ou algo assim)touch xy_0_10000.tar.gz && { _the full command here_ ; }
.gz
Arquivo.-r
acrescentar, mas-a
auto-compressa que não é equivalente. E-rz
não funciona:zip
pode adicionar a um arquivo existente porque o diretório não está compactado, mastar
com compactação comprime os metadados junto com os dados. Você podetar -r
por partes em um descompactado arquivar e depois gzip o resultado. Ou ...Não há necessidade de
xargs
. Se você der diretamentetar
a-T -
opção vai leia os nomes dos arquivos da entrada padrão.Por exemplo:
fonte
...| tar Tczf xy_...
,...| tar Tcz -f xy_...
...| tar -czf xy_... -T
e várias outras permutações, mas estou ficando apenastar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
,tar: -f: Cannot stat: No such file or directory
se usando-f
separadamente de outras opções etar: option requires an argument -- 'T'
. Você poderia por favor adicionar um exemplo de uso?-T -
no final detar
lista de opções não funcionou, mas o seu exemplo fez. Infelizmente, minha pergunta realmente tinha duas partes - a fonte do erro e uma possível melhora. Enquanto você agia no último, Archemar era excelente no primeiro e quase tinha o último direito. Não tenho certeza de qual das suas respostas aceitar, já que ambas foram obviamente úteis.Eu quero complementar as outras duas respostas com um zsh solução, que nem analisa ls , nem precisa xargs . No entanto, não tenho certeza agora, se ele também sofre com a limitação do comprimento da linha de comando.
Defina uma função que gere sua chave de classificação desejada modificando
$REPLY
.Isso é equivalente ao seu
sort -n -k1.4,1.9
Gere uma matriz
$files
com os nomes de arquivos classificados com a função acima:Isso é equivalente a
ls | sort -n -k1.4,1.9
Retornar os primeiros 10 000 arquivos com
Isso é equivalente a
ls | sort -n -k1.4,1.9 | head -n10000
Então, tudo isso deve fazer o truque:
fonte