Aqui está um processo de duas etapas muito simples para fazer exatamente isso.
Primeiro, use find
para gerar a lista de todos os arquivos que devem ser arquivados. Use sed
para gerar o nome do arquivo para cada um. Filtre a saída por meio de sort
e uniq
para garantir que você tenha os nomes de todos os arquivos necessários. Por exemplo:
find . -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_*' -printf '%f\n' | sed -e 's|_.*$||g' | sort | uniq
Note que usamos o formato %f
acima, para obter apenas os nomes dos arquivos, não os caminhos completos.
Em seguida, canalizamos isso por meio de um pequeno loop bash que lê cada nome de arquivo, usando find
novamente para localizar todos os arquivos de log, canalizando essa lista para tar
gerando o archive.
Para executar esses comandos, eu gostaria de garantir que estamos usando o código do idioma C / POSIX (sem mensagens de erro localizadas ou outra formatação). Isso é feito definindo as variáveis de ambiente LANG
e LC_ALL
como C
. Então, toda a sequência de comandos que eu usaria é
export LANG=C LC_ALL=C
find . -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_*' -printf '%f\n' | sed -e 's|_.*$||g' | sort | uniq | while read NAME ; do
find . -name "${NAME}_*.log" -printf '%p\n' | tar -cJf "${NAME}.tar.xz" -T - --no-unquote
done
O parâmetro -J
em -cJf
refere-se à compactação XZ (é rápido e bom, você provavelmente quer isso); Eu gosto de ler -cJf
como "criar arquivo XZ". Os -T -
significam que os arquivos em cada archive são fornecidos a partir da entrada padrão e --no-unquote
significa que os nomes dos arquivos são brutos, não citados.
Observe que o padrão dos nomes dos arquivos é muito adequado para globbing aqui. (Ou seja, podemos fornecê-lo a find -name ...
.) Se o padrão continha *
, ?
, [
ou ]
, precisaríamos escapar deles. Doable, mas irritante. O OP escolheu o padrão do nome do arquivo muito bem, na minha opinião.