Perl ile, sayı sırasını sıkıştırmak için Set::IntSpan
modülünü kullanabilirsiniz.
Aşağıdaki çözüm, karma ve sırasız site listelerini işleyebilir. Böyle
infile
web3.maxi.com
web4.maxi.com
web5.maxi.com
mail1.mexi.com
web6.maxi.com
web9.maxi.com
web9.maxi.com
web11.maxi.com
mail3.mexi.com
web7.maxi.com
mail4.mexi.com
mail25.mexi.com
mail26.mexi.com
mail27.mexi.com
mail28.mexi.com
web8.maxi.com
mail29.mexi.com
mail110.mexi.com
web1.maxi.com
parse.pl
#!/usr/bin/perl -l
use Set::IntSpan;
use File::Slurp qw/slurp/;
$str = slurp(\*STDIN);
# Remove redundant whitespace
chop $str;
$str =~ s/^[\t ]+|[\t ]+$//gm;
$str =~ s/\R+/\n/g;
# Copy $str so we can match numbers in it without disturbing the loop
$nums = $str;
# Parse lines in $str in sequence
while($str =~ /^(.*)$/gm) {
$line = $1;
# Extract bits before and after number
($pre, $post) = $line =~ /([^\d]+)\d+(.*)$/m;
# Check if its been printed already
next if $seen{$pre . $post};
# If not, extract numbers
@numbers = $nums =~ /$pre(\d+)$post/g;
print $pre . "["
. Set::IntSpan->new(@numbers)->run_list()
. "]" . $post;
$seen{$pre . $post} = 1;
}
Run it:
perl parse.pl < infile
Çıktı:
web[1,3-9,11].maxi.com
mail[1,3-4,25-29,110].mexi.com
Belki de şifreli @numbers = $nums =~ /$pre(\d+)$post/g
düzenli ifade ile eşleşen bir dizi öğeye genişler ve @numbers
içine kaydeder.
Bu çözümün tüm dosyayı belleğe yüklediğini unutmayın.