Perl:从文件中的每一行抓取第n和第m个定界字
由于在Nagios中添加要监视的主机的方法比较繁琐(与以前的程序仅需要IP和主机名相对,它需要定义一个主机对象,而以前的程序则需要定义一个主机对象),所以我认为最好自动执行此操作,并且这将是学习Perl的好时机,因为目前我所知道的只是C / C ++和Java。
我从中读取的文件如下所示:
xxx.xxx.xxx.xxx hostname #comments. i.dont. care. about
我想要的只是前2个字符。这些显然是用空格分隔的,但是为了通用起见,它也可能是任何东西。为了使它更笼统,为什么不选择第一和第三,或者第四和第十?当然,必须涉及到一些正则表达式操作,但是为了以防万一,我暂时暂时不使用该标签。
解决方案
一个简单的单线是
perl -nae 'print "$F[0] $F[1]\n";'
我们可以使用-F更改定界符
让我们把它变成代码高尔夫!根据David的出色回答,这是我的:
perl -ane 'print "@F[0,1]\n";'
编辑:真正的高尔夫投稿看起来更像这样(取消了五招):
perl -ape '$_="@F[0,1] "'
但这对于这个问题的目的来说不太容易理解。 :-P
大卫·内姆(David Nehme)说:
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)
联机帮助页的一部分。
这是一个通用的解决方案(如果我们稍微远离代码编程的话)。
#!/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];
当然,如果我们要分析用冒号分隔的文件,则很有可能此类文件没有注释,也不必剥离它们。
如果我们不编写更多的Perl来处理结果,那么单行代码就很棒。
不过,更一般而言,在较大的Perl程序的上下文中,我们可以编写一个自定义的正则表达式,例如:
if($line =~ m/(\S+)\s+(\S+)/) { $ip = ; $hostname = ; }
...或者我们将使用split运算符。
my @arr = split(/ /, $line); $ip = $arr[0]; $hostname = $arr[1];
无论哪种方式,都添加逻辑以检查无效输入。
自从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