这是我正在处理的日志文件 -
|
blah1a
blah1b
blah1c
|
****blahnothing1
|
blah2a
blah2b
blah2c
|
blahnothing2
|
blah3a
blah3b
blah3c
|
blahnothing3
我需要的信息位于两个管道字符之间。从asteriks开始有很多行,我跳过它们。每行都有windows行尾字符。这些管道字符之间的数据是有余的,但是当在linux主机上读取时,它会被windows新行切断。 我在两行之间编写了一个带有范围运算符的perl脚本,希望以管道分隔符开头的所有内容都会被推入数组元素,然后停在下一个管道分隔符,然后重新开始。每个数组元素都包含两个管道字符之间的所有行。
理想情况下,数组看起来像这样,没有Windows控件字符。
$lines[0] blah1a blah1b blah1c
$lines[1] blah2a blah2b blah2c
$lines[2] blah3a blah3b blah3c
但是每个阵列看起来都不一样。
#!/usr/bin/perl
use strict ;
use warnings ;
my $delimiter = "|";
my $filename = $ARGV[0] ;
my @lines ;
open(my $fh, '<:encoding(UTF-8)' , $filename) or die "could not open file $filename $!";
while (my $line = readline $fh) {
next if ($line =~/^\*+/) ;
if ($line =~ /$delimiter/ ... $line =~/$delimiter/) {
push (@lines, $line) ;
}
}
print $lines[0] ;
print $lines[1] ;
print $lines[2] ;
答案 0 :(得分:2)
这似乎符合您的要求
我已将两行blahnothing2
和blahnothing3
留在原位,因为我看不到删除它们的理由
\R
正则表达式模式是通用换行符,并匹配来自任何平台的换行符序列,即CR,LF或CRLF
use strict;
use warnings 'all';
my $data = do {
open my $fh, '<:raw', 'blah.txt' or die $!;
local $/;
<$fh>;
};
$data =~ s/^\s*\*.*\R/ /gm; # Remove lines starting with *
$data =~ s/\R/ /g; # Change all line endings to spaces
# Split on pipe and remove blank elements
my @data = grep /\S/, split /\s*\|\s*/, $data;
use Data::Dump;
dd \@data;
[
"blah1a blah1b blah1c",
"blah2a blah2b blah2c",
"blahnothing2",
"blah3a blah3b blah3c",
"blahnothing3 ",
]
答案 1 :(得分:1)
您似乎希望将|
之间的行合并为一个字符串,该字符串将放置在数组中。
一种方法是将|
设置为input record separator,因此每次在管道之间读取一个块
{ # localize the change to $/
local $/ = "|";
open(my $fh, '<:encoding(UTF-8)' , $filename)
or die "could not open file $filename $!";
my @records;
while (my $section = <$fh>)
{
next if $section =~ /^\s*\*/;
chomp $section; # remove the record separator (| here)
$section =~ s/\R/ /g; # clean up newlines
$section =~ s/^\s*//; # clean up leading spaces
push @records, $section if $section;
}
print "$_\n" for @records;
}
如果使用*
启动(以及可选空格),我会跳过“部分”。可以有更多限制版本。 $section
最终可能是一个emtpy字符串,因此我们有条件地在数组上push
。
输出,问题中的示例通过$filename
blah1a blah1b blah1c blah2a blah2b blah2c blahnothing2 blah3a blah3b blah3c blahnothing3
问题中的方法很好,但您需要合并“部分”(管道之间)中的行并将每个这样的字符串放在数组上。因此,您需要一个标记来跟踪进入/离开某个部分的时间。