Perl:如何在两个相同模式之间打印线条?
Perl : How to print lines in between two of the same patterns?
我有一些数据叫做 data_range.txt。最终我想将数据加载到数组中并比较字符串。但是我无法打印这两个 -- 模式之间的线条。
--
2020-10-07T22:14:27,545 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=191216CV0
2020-10-07T22:14:27,554 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@
--
2020-10-07T22:43:12,345 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=00774MAB1
2020-10-07T22:43:12,354 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@
--
2020-10-07T22:44:02,028 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=00774MAB1
2020-10-07T22:44:02,036 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@
--
2020-10-07T22:55:10,691 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=71647NBE8
2020-10-07T22:55:10,703 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@
--
我有一个脚本,当我尝试在两种不同的模式之间打印时通常可以使用,但是这些模式是相同的。
#!/usr/bin/perl
use warnings;
use strict;
my $file = 'data_range.txt';
open my $fh, $file or die "Can't open $file: $!";
# Build the start and end patterns
my $beg = qr/--/;
my $end = qr/--/;
while (<$fh>)
{
if (/$beg/ .. /$end/) {
print if not /$end/;
}
}
您需要稍微修改一下条件,不要跳过第二部分
if (/--/ .. /--/ && next) {
print;
}
但放弃范围运算符并改用输入记录分隔符可能更简洁:
local $/ = "--\n";
while (<>) {
# Here $_ contains all the lines of a section
my @lines = split /\n/;
# ...
}
使用 grep
预处理输入以删除 --
行,并使用 paste
将输入更改为每行 2 条记录的文件,默认情况下加入选项卡。通过在选项卡上将记录拆分为每行 2 条记录的数组,可以轻松解析结果。
grep -v '^--' data_range.txt | paste - - | perl -F'\t' -lane 'print join "\t", map { qq{"$_"} } @F;'
# Prints:
"2020-10-07T22:14:27,545 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=191216CV0" "2020-10-07T22:14:27,554 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@"
"2020-10-07T22:43:12,345 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=00774MAB1" "2020-10-07T22:43:12,354 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@"
"2020-10-07T22:44:02,028 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=00774MAB1" "2020-10-07T22:44:02,036 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@"
"2020-10-07T22:55:10,691 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=71647NBE8" "2020-10-07T22:55:10,703 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@"
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
-a
: 在空格或 -F
选项中指定的正则表达式上将 $_
拆分为数组 @F
。
-F'/\t/'
: 在 TAB 上拆分为 @F
,而不是在空格上。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches
我有一些数据叫做 data_range.txt。最终我想将数据加载到数组中并比较字符串。但是我无法打印这两个 -- 模式之间的线条。
--
2020-10-07T22:14:27,545 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=191216CV0
2020-10-07T22:14:27,554 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@
--
2020-10-07T22:43:12,345 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=00774MAB1
2020-10-07T22:43:12,354 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@
--
2020-10-07T22:44:02,028 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=00774MAB1
2020-10-07T22:44:02,036 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@
--
2020-10-07T22:55:10,691 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=71647NBE8
2020-10-07T22:55:10,703 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@
--
我有一个脚本,当我尝试在两种不同的模式之间打印时通常可以使用,但是这些模式是相同的。
#!/usr/bin/perl
use warnings;
use strict;
my $file = 'data_range.txt';
open my $fh, $file or die "Can't open $file: $!";
# Build the start and end patterns
my $beg = qr/--/;
my $end = qr/--/;
while (<$fh>)
{
if (/$beg/ .. /$end/) {
print if not /$end/;
}
}
您需要稍微修改一下条件,不要跳过第二部分
if (/--/ .. /--/ && next) {
print;
}
但放弃范围运算符并改用输入记录分隔符可能更简洁:
local $/ = "--\n";
while (<>) {
# Here $_ contains all the lines of a section
my @lines = split /\n/;
# ...
}
使用 grep
预处理输入以删除 --
行,并使用 paste
将输入更改为每行 2 条记录的文件,默认情况下加入选项卡。通过在选项卡上将记录拆分为每行 2 条记录的数组,可以轻松解析结果。
grep -v '^--' data_range.txt | paste - - | perl -F'\t' -lane 'print join "\t", map { qq{"$_"} } @F;'
# Prints:
"2020-10-07T22:14:27,545 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=191216CV0" "2020-10-07T22:14:27,554 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@"
"2020-10-07T22:43:12,345 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=00774MAB1" "2020-10-07T22:43:12,354 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@"
"2020-10-07T22:44:02,028 DEBUG [recvMsgProc-0] <KdbQMHandler> calling:parameters=00774MAB1" "2020-10-07T22:44:02,036 INFO [recvMsgProc-0] <KdbQMHandler> resultkx.Flip@"
"2020-10-07T22:55:10,691 DEBUG [recvMsgProc-1] <KdbQMHandler> calling:parameters=71647NBE8" "2020-10-07T22:55:10,703 INFO [recvMsgProc-1] <KdbQMHandler> resultkx.Flip@"
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
-a
: 在空格或 -F
选项中指定的正则表达式上将 $_
拆分为数组 @F
。
-F'/\t/'
: 在 TAB 上拆分为 @F
,而不是在空格上。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches