2012-09-19 1 views
8

Im Folgenden finden Sie eine Liste der Hostnamen, die in einer Textdatei gespeichert sind.Hostnamen analysieren und neu anordnen

web1.maxi.com 
web3.maxi.com 
web4.maxi.com 
web5.maxi.com 
web6.maxi.com 
web7.maxi.com 
web8.maxi.com 
web9.maxi.com 
web11.maxi.com 

aus Gründen es kurz anzuzeigen es analysiert werden muss und neu geschrieben/angezeigt, wie

web[1,3-9,11].maxi.com 

können ihr mir auf diesem helfen, werden alle Vorschläge hilfreich sein.

Antwort

3

Mit Perl können Sie das Set::IntSpan Modul zum Komprimieren der Zahlenfolge verwenden.

Die folgende Lösung kann gemischte und ungeordnete Standortlisten verarbeiten.

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 es wie folgt aus:

perl parse.pl < infile 

Ausgang:

web[1,3-9,11].maxi.com 
mail[1,3-4,25-29,110].mexi.com 

Die vielleicht kryptische @numbers = $nums =~ /$pre(\d+)$post/g wird zu einem Array von Elementen erweitert, die dem regulären Ausdruck entsprechen, und wird in @numbers gespeichert.

Beachten Sie, dass diese Lösung die gesamte Datei in den Speicher lädt.

3
with open("data.txt") as f: 
    sites=[x.strip() for x in f] 
    ranges=[] 
    for x in sites: 
     x=x.split(".") 
     num=int(x[0][x[0].index("web")+3:]) 
     if ranges: 
      if num-ranges[-1][-1]==1: 
       ranges[-1].append(num) 
      else: 
       ranges.append([num])  
     else: 
      ranges.append([num])   
    print ranges 
    print "web["+",".join(str(x[0]) if len(x)==1 else str(x[0])+"-"+str(x[-1]) for x in ranges)+"].maxi.com" 

Ausgang:

[[1], [3, 4, 5, 6, 7, 8, 9], [11]] 
web[1,3-9,11].maxi.com 
0

Mein Nehmen auf sie:

#print hosts 
lines = open("log.txt").readlines() 
numbers = [int(line.split(".")[0][3:]) for line in lines] 
out = [[]] 
index = 0 
for i in xrange(len(numbers) - 1): 
    out[index].append(numbers[i]) 
    if (numbers[i + 1] - numbers[i] != 1): 
     out.append([]) 
     index += 1 
out[-1].append(numbers[-1]) 
strings = [str(number[0]) if len(number) == 1 else str(number[0]) + "-" + str(number[-1]) for number in out] 
print ",".join(strings) 

Wäre gut, um die Schleife zu etwas mehr pythonic/functional zu ändern.