【问题标题】:parse and rearrange hostnames解析和重新排列主机名
【发布时间】:2012-09-11 09:11:22
【问题描述】:

以下是存储在文本文件中的主机名列表。

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

为了尽快显示它,需要对其进行解析和重写/显示为

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

你们能帮我解决这个问题吗,任何建议都会有所帮助。

【问题讨论】:

    标签: c++ python perl awk


    【解决方案1】:

    使用 perl,您可以使用 Set::IntSpan 模块来压缩数字序列。

    以下解决方案可以处理混合和无序的网站列表。

    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;
    }
    

    像这样运行它:

    perl parse.pl < infile
    

    输出:

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

    可能很神秘的@numbers = $nums =~ /$pre(\d+)$post/g 扩展为由正则表达式匹配的项目数组,并将其保存在@numbers 中。

    请注意,此解决方案会将整个文件加载到内存中。

    【讨论】:

      【解决方案2】:
      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"
      

      输出:

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

      【讨论】:

        【解决方案3】:

        我的看法:

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

        将循环更改为更 Pythonic/功能性的东西会很好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-14
          • 1970-01-01
          • 2020-12-16
          • 1970-01-01
          • 2017-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多