Este é um conceito que me interessa por um tempo, embora eu não tenha conseguido escrever um roteiro para ele ainda, já que estou um pouco ocupado!
Não existe uma maneira fácil para o software saber realmente o que algo irá compactar, sem executar os arquivos através do algoritmo primeiro (lembre-se, o tar é apenas um arquivador, não um utilitário de compactação) mas você pode usá-lo com gzip). A outra opção (mais fácil) seria continuar adicionando arquivos ao arquivo e, em seguida, verificar o tamanho de cada vez. Eu não sei de nenhuma solução pronta para conseguir isso, mas ela pode ser implementada em algumas linhas de código!
A lógica básica seria algo assim:
Isso depende de qual utilitário você também usa. Alguns não têm opções que permitem remover facilmente um arquivo do arquivo morto, portanto, talvez seja necessário adicionar uma segunda variável de entrada para a folga. Essa segunda variável pode determinar o tamanho máximo estimado de um arquivo no diretório e, se o arquivo for maior que esse tamanho, ele será incluído no arquivo. Se não houvesse espaço suficiente, o arquivo fecharia e criaria um novo. É claro, você pode ajustar esse algoritmo no infinito, garantindo que o tamanho do próximo arquivo seja verificado e comparado com o tamanho atual do arquivo. Você provavelmente também vai querer usar os arquivos maiores primeiro, então como você pode ver muita lógica pode entrar nisso.
Infelizmente, esta não é uma solução completa, mas espero que seja um bom ponto de partida!