【发布时间】:2015-07-24 15:16:28
【问题描述】:
我有一个小程序,它接受用户输入,应该从包含指定“端口”的文本文件中过滤掉特定行。文本文件如下所示:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
我编写的脚本只是提示用户输入,并且应该使用结合输入变量的正则表达式来过滤数据。使用网站 www.rubular.com 我可以让我的表达式按预期工作,但在实际代码中我没有得到任何列出的数据。
以下是我的 Perl 脚本:
use warnings;
use strict;
my $port_query = 1;
my $command = "ss -p -l -n -t -u -4";
my $port = 0;
my $output_file = "system_output.txt";
while ($port_query == 1) {
print "Please choose the port number (Numerical value):\n";
$port = <>;
if ($port =~ /^[0-9]{1,5}+$/) {
$port_query = 0;
}
else {
print "Argument not allowed.\n";
}
}
system ("touch $output_file"); #Creates the output file.
system ("$command > $output_file"); #Executing system commands
open(INPUT, "<", "$output_file") or die ("Unable to write to file.");
chomp(my @socket_data = <INPUT>);
close (INPUT);
foreach my $line(@socket_data) {
if ($line =~ /\S+?([0-9]|0*):($port)/) {
print "$line\n";
}
}
脚本应该打印一行,即:
LISTEN 0 128 *:22 *:*
【问题讨论】:
-
<是读取模式,而不是写入模式,正如您的die消息所暗示的那样。此外,您不需要将输出存储在临时文件中,只需将其存储在变量中:chomp(my @socket_data = qx($command))。而按照这种思路,你也可以跳过循环:= grep /[0-9]:$port/, qx($command) -
另外,您的脚本可以简化为 bash 脚本,使用
ss ... | grep ... -
我知道我可以稍微缩短脚本,但它是用于学习目的。我也尝试过“grep”方法,但我无法以足够的准确度将其 grep。
-
@MajesticPixel 在这种情况下,grep 和 foreach 的准确性没有区别。如果您使用相同的正则表达式,结果应该是相同的。否则,你做错了什么。
-
我明白了。我不知道正则表达式可以与“grep”一起使用。谢谢你的信息。