8

由于在 Nagios 中添加要监控的主机的方式更为繁琐(它需要定义一个主机对象,而不是之前只需要 IP 和主机名的程序),我认为最好自动化它,它会是学习 Perl 的好时机,因为我现在只知道 C/C++ 和 Java。

我从中读取的文件如下所示:

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

我想要的只是前两串字符。这些显然是用空格分隔的,但为了通用性,它也可以是任何东西。为了更笼统地说,为什么不是第一和第三,或第四和第十?当然,肯定会涉及到一些正则表达式操作,但我暂时不考虑这个标签,以防万一。

4

7 回答 7

9

如果您不编写更多 Perl 来处理结果,那么单行代码很棒。

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

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

...或者您将使用拆分运算符。

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

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

于 2008-10-01T03:01:16.930 回答
7

让我们把它变成代码高尔夫!根据大卫的出色回答,这是我的:

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

编辑:一个真正的高尔夫提交看起来更像这样(剃掉五杆):

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

但这对于这个问题的目的来说不太可读。:-P

于 2008-10-01T02:43:27.657 回答
7

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

#!/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按空格分割。如果这不是您想要的(例如 parsing /etc/passwd),您可以将分隔符作为正则表达式传递:

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

当然,如果您正在解析以冒号分隔的文件,那么这些文件也很有可能没有注释并且您不必删除它们。

于 2008-10-01T02:47:26.620 回答
6

一个简单的单线是

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

您可以更改分隔符-F

于 2008-10-01T02:38:33.613 回答
4

大卫尼姆说:

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.

你每天都学到一些东西。-n 使每一行都传递给

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

最后-e是一种直接输入单行程序的方法。您可以拥有超过-e. 其中大部分是手册perlrun(1)页的翻版。

于 2008-10-01T02:46:15.280 回答
0

既然 ray 问了,我想我会重写我的整个程序而不使用 Perl 的隐含性(除了使用<ARGV>; 这很难用手写出来)。这可能会让 Python 人更快乐(尽管有大括号:-P):

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+/?' '/\s+/相似呢,除了如何处理行首的空格。所以' '真的很神奇。)

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

于 2008-10-01T23:32:29.653 回答
0

在第 L 行中查找第 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

另存为查找标签.cmd

结果将是您的 Drive E 标签

享受

于 2013-12-31T04:55:55.233 回答