2012-09-19 11 views
8

A continuación se muestra una lista de nombres de host que se almacenan en un archivo de texto.analizar y reorganizar nombres de host

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 

en aras de mostrar lo poco que tiene que ser analizada y reescrita/muestra como

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

pueden ustedes ayudarme en esto, todas las sugerencias serán útiles.

Respuesta

3

Con perl puede usar el módulo Set::IntSpan para comprimir la secuencia numérica.

La siguiente solución puede manejar listados de sitios mixtos y desordenados.

archivoentrada

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 así:

perl parse.pl < infile 

Salida:

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

El quizás críptico @numbers = $nums =~ /$pre(\d+)$post/g se expande a una matriz de elementos que coinciden con la expresión regular y la guarda en @numbers.

Tenga en cuenta que esta solución carga todo el archivo en la memoria.

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" 

de salida:

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

Mi opinión sobre ella:

#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) 

sería bueno cambiar el bucle a algo más Pythonic/funcional.

Cuestiones relacionadas