我正在写一个perl脚本..我是perl的新手。这是我的代码
use warnings;
use strict;
my $file = $ARGV[0] ;
my $file2 = 'output.txt';
open FH, $file or die $!;
open FHH, "> $file2" or die $!;
while(<FH>) {
if(/SIB_DBG/) {
my $val = $_;
if($val = /TTRB:([\da-f]+)/) {
print "$1 \n";
}
}
}
这是输入文件的一行
Aug 31 15:25:53 usb3 kernel: [ 78.813721] SIB_DBG TTRB:00000000 00000000 00000000 00001021, PTR: ffff88005ff8b850
我能够在TTRB
之后立即分离8字节的第一个字段。但是之后如何将三个字段分开?
答案 0 :(得分:2)
你遇到的问题是微不足道的,因为重复正则表达式会从字符串中提取更多数据。不过,我还有其他一些要点可以分享。
open
的三个参数版本,并使用词法文件句柄。例如:open my $fh, "<", $file or die $!
while (<>) { ... }
。在命令行中,这是-n
和-p
开关的作用。perl foo.pl input.txt > output.txt
。还要注意代码的这一部分:
if($val = /TTRB:([\da-f]+)/) {
当您打算使用绑定运算符=
时,您正在使用赋值运算符=~
。结果是,$val
的内容不是$_
,而是$val
的内容。然后将该检查的返回值分配给 if($val = $_ =~ /TTRB:([\da-f]+)/) {
。它与写作相同
$_
因为没有绑定运算符的正则表达式匹配总是默认检查use strict;
use warnings;
while(<>) {
if (/SIB_DBG/) {
if (/TTRB:((?:[\da-f]+\s*)+)/) {
print "$1 \n";
}
}
}
。
perl -nle 'print /SIB_DBG\s+TTRB:((?:[\da-f]+\s*)+)/' input.txt > output.txt
这将简单地匹配重复的字母数字序列并打印它们。你应该注意到这可以简化很多,直到最基本的单行:
print
正则表达式的匹配将返回-l
,直接打印,synchronized (NThread.baton)
开关将添加换行符。
答案 1 :(得分:1)
您可以在标量上下文中使用Perl全局正则表达式匹配(使用/g
修饰符)。这使匹配只找到模式的 next 出现,因此您可以逐步处理字符串
该程序首先检查它是否可以在字符串中找到TTRB:
,如果没有则跳过它。但是当它找到字符串时,它会在TTRB:
之后留下一个特定于该字符串的内部指针,以便下一个全局匹配将从那里开始查看
然后它找到所有出现的八个十六进制数字,可能后跟一些空格。 \G
锚点强制每个匹配开始与前一个匹配结束的位置完全相同,因此当它到达00001021
后面跟一个逗号时,下一个搜索将失败,因为该模式要求接下来的八个数字开始逗号在哪里
我仅使用Data::Dump
在操作后显示@data
的内容
use strict;
use warnings;
use Data::Dump;
while ( <DATA> ) {
next unless /TTRB:/g;
my @data = /\G(\p{hex}{8})\s*/g;
dd \@data;
}
__DATA__
Aug 31 15:25:53 usb3 kernel: [ 78.813721] SIB_DBG TTRB:00000000 00000000 00000000 00001021, PTR: ffff88005ff8b850
["00000000", "00000000", "00000000", "00001021"]
答案 2 :(得分:0)
试试这个:
if($val =~ /TTRB:([\da-f]+)\s([\da-f]+)\s([\da-f]+)\s([\da-f]+)/)
{
print "$1 $2 $3 $4\n";
}
$ 1包含前8个字节 $ 2包含第二个8字节,依此类推