Linux

Linux

Então, tenho cerca de 20.000 arquivos que desejo compactar e agrupar seguindo a lógica:

  • compactar todos os arquivos que possuem caracteres idênticos até(
  • também incluem arquivos que não possuem(

Então os arquivos são como

file_123.foo
file_123(abc).foo
file_123(b9)(ca)[a1].foo

foobar(a).foo
foobar.foo
foobar(123).foo

que deve ser comprimido para

file_123.7z
foobar.7z

Estou aberto a arquivos em lote do Windows, scripts Unix ou qualquer programa de compactação (posso trabalhar a partir daí), embora a combinação mais conveniente seja .7z e Windows.

ATUALIZAR

cYrus me deu uma resposta perfeita, o problema é que minha pergunta não era precisa o suficiente :) Agora que sou mais inteligente, aqui está o próximo conjunto de problemas que ainda não descobri como resolver:

Então tudo funciona perfeitamente, a menos que isso aconteça:

file_123(abc).foo
file_123456789(b9).foo

Esses dois não devem ser agrupados, ou seja, devem terminar em dois arquivos separados:

file_123.7z
file_123456789.7z

Este:

for pfx in $(for i in *.foo; do echo "${i%%[.(]*}"; done | sort -u); do 7z a "$pfx.7z" $pfx*; done

cria esses dois separadamente,maso arquivo mais curto funciona como um pega-tudo, ou seja, file_123.7zinclui ambos os arquivos, o que não deveria.

Responder1

Linux

Isso deve funcionar:

for pfx in $(for i in *.foo; do echo "${i%%[.(]*}"; done | sort -u); do 7z a "$pfx.7z" $pfx[.\(]*; done

Explicação

Primeiro temos que iterar todos os arquivos de entrada ( *.foo) e retirar o sufixo ( ${i%%[.(]*}) obtendo:

file_123
file_123
file_123
foobar
foobar
foobar

Então podemos remover duplicatas com sort -u:

file_123
foobar

Finalmente, para cada prefixo ( $pfx) podemos construir o arquivo usando o próprio prefixo como nome do arquivo ( "$pfx.7z") e padrão para identificar os arquivos ( $pfx[.\(]*); obtendo o equivalente a:

7z a file_123.7z 'file_123(abc).foo' 'file_123(b9)(ca)[a1].foo' 'file_123.foo'
7z a foobar.7z 'foobar(123).foo' 'foobar(a).foo' 'foobar.foo'

Responder2

Ok, em vez de apenas fornecer um script de shell, vou mostrar o menu de contexto do 7zips.

Passo 1: Abra sua pasta com todos esses arquivos.

Passo 2: Clique em "Nome" para ordenar todos os arquivos por nome (isso facilitará a seleção de arquivos com nomes semelhantes).

etapa 3: Com ocertobotão do mouse, arraste e solte a caixa de seleção sobre todos os arquivos que deseja compactar em um único arquivo (Então, foobar(a).foo, foobar.foo ,foobar(123).foo )

Passo 4: Ao soltar o botão direito do mouse, o menu de contexto aparecerá. Vá para 7Zip> Adicionar a PARENT_DIRECTORY.7z

Onde PARENT_DIRECTORY é o nome da pasta em que esses arquivos estão. Portanto, se a pasta em que você está se chamar 'files', ele os adicionará a 'files.7z'

Etapa 5: Renomeie este novo arquivo compactado clicando com o botão direito no novo arquivo 7Zip e clicando em 'Renomear'.

informação relacionada