我有一个非常基本的perl脚本,它在匹配搜索模式后打印文本文件中的下一行。
@ARGV = <dom_boot.txt>;
while ( <> ) {
print scalar <> if /name=sacux445/;
}
哪个有效,但是我想将输出捕获到文件中以供进一步使用,而不是将其打印到STDOUT
。
我只是在学习(慢慢地),所以尝试了这个:
my $fh;
my $dom_bootdev = 'dom_bootdev.txt';
open ($fh, '>', $dom_bootdev) or die "No such file";
@ARGV = <dom_boot.txt>;
while ( <> ) {
print $fh <> if /name=sacux445/;
}
close $fh;
但是我收到语法错误。
在try.plx第19行的语法错误,靠近“&lt;&gt;”
我正在努力解决这个问题。我猜它可能非常简单,所以任何帮助都会受到赞赏。
谢谢, 路加。
答案 0 :(得分:3)
答案 1 :(得分:2)
如果线条匹配模式,只需获取循环中的下一行并打印它:
while (<>) {
next unless /name=sacux445/;
my $next = <>;
last unless defined $next;
print $fh $next;
}
注意,您需要检查菱形运算符的返回值。
输入
name=sacux445 (1)
aaa
name=sacux445 (2)
bbb
name=sacux445 (3)
输出
aaa
bbb
答案 2 :(得分:0)
应该学习使用状态机来解析数据。状态机允许输入读取仅在代码中的一个位置。将代码重写为状态机:
use strict;
use warnings;
use autodie; # See http://perldoc.perl.org/autodie.html
my $dom_bootdev = 'dom_bootdev.txt';
open ( my $fh, '>', $dom_bootdev ); # autodie handles open errors
use File::Glob qw( :bsd_glob ); # Perl's default glob() does not handle spaces in file names
@ARGV = glob( 'dom_boot.txt' );
my $print_next_line = 0;
while( my $line = <> ){
if( $line =~ /name=sacux445/ ){
$print_next_line = 1;
next;
}
if( $print_next_line ){
print {$fh} $line;
$print_next_line = 0;
next;
}
}
何时使用状态机
如果数据是无上下文的,则只能使用正则表达式进行解析。
如果数据具有树结构,则可以使用简单的状态机对其进行解析。
对于更复杂的结构,至少需要一个带有下推式堆栈的状态机。堆栈记录先前的状态,以便当前状态结束时机器可以返回它。
使用的最复杂的数据结构是XML。它需要一个状态机来处理它的语法,第二个需要一个堆栈用于它的语义。