Il seguente programma perl prende file compressi in altri formati (.tar.gz, .tgz, .tar.Z e .Z) e li rimpacchetta per una migliore compressione. Il sorgente perl ha tutti i tipi di documentazione su cosa fa e come lo fa. Quest'ultima versione riceve i file come input dalla riga di comando. Senza argomenti da riga di comando tenta di ricomprimere tutti i file contenuti nell'attuale directory.
#!/usr/bin/perl -w
#######################################################
# #
# Questo programma prende i programmi compressi #
# nella directory attuale e li converte nel formato #
# bzip2. Gestisce l'etensione .tgz in un modo #
# ragionevole, producendo un file .tar.bz2. #
# #
#######################################################
$counter = 0;
$saved_bytes = 0;
$totals_file = '/tmp/machine_bzip2_total';
$machine_bzip2_total = 0;
@raw = (defined @ARGV)?@ARGV:<*>;
foreach(@raw) {
next if /^bzip/;
next unless /\.(tgz|gz|Z)$/;
push @files, $_;
}
$total = scalar(@files);
foreach (@files) {
if (/tgz$/) {
($new=$_) =~ s/tgz$/tar.bz2/;
} else {
($new=$_) =~ s/\.g?z$/.bz2/i;
}
$orig_size = (stat $_)[7];
++$counter;
print "Ricompressione $_ ($counter/$total)...\n";
if ((system "gzip -cd $_ |bzip2 >$new") == 0) {
$new_size = (stat $new)[7];
$factor = int(100*$new_size/$orig_size+.5);
$saved_bytes += $orig_size-$new_size;
print "$new è circa il $factor% della dimensione di $_. :",($factor<100)?')':'(',"\n";
unlink $_;
} else {
print "Arrgghh! È successo qualcosa a $_: $!\n";
}
}
print "Si sono "
, ($saved_bytes>=0)?"guadagnati ":"persi "
, abs($saved_bytes)
, " byte di spazio :"
, ($saved_bytes>=0)?")":"("
, "\n"
;
unless (-e '/tmp/machine_bzip2_total') {
system ('echo "0" >/tmp/machine_bzip2_total');
system ('chmod', '0666', '/tmp/machine_bzip2_total');
}
chomp($machine_bzip2_total = `cat $totals_file`);
open TOTAL, ">$totals_file"
or die "Impossibile aprire il totale su tutto il sistema: $!";
$machine_bzip2_total += $saved_bytes;
print TOTAL $machine_bzip2_total;
close TOTAL;
print "Sono stati guadagnati un totale di ",`cat $totals_file`," byte su tutta la macchina.\n";