【问题标题】:How can I grep a paragraph in Perl?如何在 Perl 中 grep 段落?
【发布时间】:2010-09-28 07:48:36
【问题描述】:

我有一个需要正确格式化为可读格式的日志文件。然而,文本文件没有静态行数或固定主值,并且有随机数量的空格,但只有一个日志文件头,可用于确定每次应用程序日志的开始和结束。

日志文件示例:

Log File header
<text>
<text>
Log File header
<text>

脚本格式化后应如下所示:

Log File header
<text>
<text>

<space>

Log File header
<text>
<text>

因此,每次 Perl 脚本检测到“日志文件头”时,我都需要一些建议来找出整个段落。

这里是 grep perl 脚本:

#!/usr/bin/perl

#use 5.010; # must be present to import the new 5.10 functions, notice 
#that it is 5.010 not 5.10

my $file = "/root/Desktop/Logfiles.log";
open LOG, $file or die "The file $file has the error of:\n =>  $!";

@lines = <LOG>;
close (LOG);

@array = grep(/Log File header/, @lines);

print @array;

有人可以就代码提供一些建议吗?谢谢。

【问题讨论】:

标签: perl grep paragraph


【解决方案1】:

所以您只希望日志文件部分之间有垂直空间?

有几种方法,特别是因为您知道标题将位于完全独立的行上。在以下所有示例中,假设 @lines 已从您的输入文件中填充。

所以第一个技巧:在标题前插入空格:

foreach my $line ( @lines ) {
    if ( $line =~ m/Log File header/ ) {
        print( "\n\n\n" ); # or whatever you want <space> to be
    }

    print( $line );
}

下一个技术是使用正则表达式来搜索/替换文本块:

my $space = "\n\n\n"; # or whatever you want <space> to be
my $everything = join( "", @lines );
$everything =~ s/(Log File header.*?)(?=Log File header)/$1$space/sg;
print( $everything );

关于正则表达式的一些解释。 (?= 表示“前瞻”,它将匹配但不构成要替换的表达式的一部分。 /sg 修饰符意味着s-将换行符视为普通空格,g-进行全局搜索和替换。 .*? 表示选择任何东西,但尽可能少地满足表达式(非贪婪),这在此应用程序中非常重要。

更新:编辑了第一个技术,其中我未能明确指定要对哪个变量进行匹配。

【讨论】:

  • 谢谢伙计!第一种技术似乎只打印整个日志而没有任何变化,但第二种技术工作得很好!再次感谢伙计!
  • 哦,我的错,我将编辑第一个答案,我没有明确指定要匹配哪个变量。您现在应该会发现第一个有效。
  • 第一个代码仍然不起作用,因为它只是再次重新打印整个日志。介意我问为什么您需要代码“my $everything = join("", @lines);"作为第二个工作代码?它对正则表达式有何贡献?跟/s有关系吗?再次感谢伙计!
  • 请查看perldoc -f join 以获取有关连接功能的文档。如果您不确定标量和数组之间的区别,那么是时候学习 Perl 的基础知识了。
猜你喜欢
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多