代码之家  ›  专栏  ›  技术社区  ›  ray

Perl:从文件中的每一行获取第n个和第mth个分隔字

  •  7
  • ray  · 技术社区  · 16 年前

    由于在Nagios中添加要监视的主机的方法比较繁琐(它需要定义一个主机对象,而以前的程序只需要IP和主机名),因此我认为最好将其自动化,这将是学习Perl的好时机,因为目前我只知道C/C++和Java。

    xxx.xxx.xxx.xxx hostname #comments. i.dont. care. about
    

    我想要的只是前两组角色。这些显然是用空格分隔的,但为了一般性,它也可以是任何东西。更一般地说,为什么不是第一个和第三个,或者第四个和第十个呢?当然,一定有一些正则表达式的行动涉及,但我会留下这个标签的时刻,以防万一。

    7 回复  |  直到 16 年前
        1
  •  9
  •   slim    16 年前

    如果您没有编写更多的Perl来处理结果,那么一行代码就很好了。

    但更一般地说,在大型Perl程序的上下文中,您可以编写自定义正则表达式,例如:

    if($line =~ m/(\S+)\s+(\S+)/) {
         $ip = $1;
         $hostname = $2;
    }
    

    分裂 操作人员

    my @arr = split(/ /, $line);
    $ip = $arr[0];
    $hostname = $arr[1];
    

    无论哪种方式,都可以添加逻辑来检查无效输入。

        2
  •  7
  •   C. K. Young    16 年前

    perl -ane 'print "@F[0,1]\n";'
    

    编辑:一个真正的高尔夫投稿看起来更像这样(减少五杆):

    perl -ape '$_="@F[0,1]
    "'
    

    但就这个问题而言,这是不可读的-P

        3
  •  7
  •   C. K. Young    16 年前

    这里有一个通用的解决方案(如果我们稍微远离代码高尔夫)。

    #!/usr/bin/perl -n
    chop;                     # strip newline (in case next line doesn't strip it)
    s/#.*//;                  # strip comments
    next unless /\S/;         # don't process line if it has nothing (left)
    @fields = (split)[0,1];   # split line, and get wanted fields
    print join(' ', @fields), "\n";
    

    split 按空格分隔。如果这不是您想要的(例如,解析 /etc/passwd ),可以将分隔符作为正则表达式传递:

    @fields = (split /:/)[0,2,4..6];
    

        4
  •  6
  •   David Nehme    16 年前

    简单的一行是

    perl -nae 'print "$F[0] $F[1]\n";'
    

    -F

        5
  •  4
  •   Trenton    16 年前

    大卫·内姆说:

    perl -nae 'print "$F[0] $F[1}\n";
    

    哪个使用 -a 转换我得查一下:

    -a   turns on autosplit mode when used with a -n or -p.  An implicit split
         command to the @F array is done as the first thing inside the implicit
         while loop produced by the -n or -p.
    

    LINE:
        while (<>) {
            ...             # your program goes here
        }
    

    最后 -e -e . 这其中的大部分是一个裂口 perlrun(1) 主页。

        6
  •  0
  •   C. K. Young    16 年前

    <ARGV>

    while (my $line = <ARGV>) {
        chop $line;
        $line =~ s/#.*//;
        next unless $line =~ /\S/;
        @fields = (split ' ', $line)[0,1];
        print join(' ', @fields), "\n";
    }
    

    有什么我错过的吗?希望不会。这个 ARGV 文件句柄是特殊的。它导致读取命令行上的每个命名文件,除非未指定任何文件,否则它将读取标准输入。

    编辑:哦,我忘了。 split ' ' 它也很神奇,不像 split / / . 后者只匹配一个空格。前者匹配任意数量的空格。如果没有为其指定模式,则默认情况下使用此神奇行为 split 但是呢 /\s+/ ? ' ' 除了如何处理行首的空格外,其他内容都是类似的。所以 ' ' 真的很神奇。)

    这个故事的寓意是,如果你喜欢很多神奇的行为,Perl是很棒的。如果您没有一条,请使用Python:-P

        7
  •  0
  •   Amit    11 年前

    在第1行中查找第n到第m个字符--查找标签的示例


    @echo off
    
    REM Next line = Set command value to a file  OR  Just Choose Your File By Skipping The Line
    vol E: > %temp%\justtmp.txt
    REM  Vol E:  = Find Volume Lable Of Drive E
    
    REM  Next Line to choose line line no. +0 = line no. 1 
    for /f "usebackq delims=" %%a in (`more +0 %temp%\justtmp.txt`) DO (set findstringline=%%a& goto :nextstep)
    
    :nextstep
    
    REM  Next line to read nth to mth Character  here 22th Character to 40th Character
    set result=%findstringline:~22,40%
    
    echo %result%
    pause
    exit /b
    

    结果将是您的驱动器E标签