这是我的输入文件
^A{1:IRVTUS30XXX}{2:I300dfaffaefa}{3:fewfa]}
:15A:
:20:1234556
:22:dsafas
dsafafaf
erwfafgr
:23:fewfd
:24:firh
:60:uncenjnjcdv
:72:uenuernfk
12345
-}^C^A{1:IRVTUS30XXX}{2:I304dfaffaefa}{3:fewfa]}
:15A:
:20:1234556
:22:dsafas
dsafafaf
erwfafgr
:23:fewfd
:24:firh
:60:uncenjnjcdv
:72:uenuernfk
12345
-}^C^A{1:IRVTUS30XXX}{2:I306dfaffaefa}{3:fewfa]}
:15A:
:20:1234556
:22:dsafas
dsafafaf
erwfafgr
:23:fewfd
:24:firh
:60:uncenjnjcdv
:72:uenuernfk
12345
-}^C
这里我想用以下命令删除几行。如果传入消息是类型300(取决于第一行中的此标记2:I300),我需要仅对^ A和^ C之间的消息执行第一个命令,其中模式I305应该在那里。 Sameway for I304我想执行第二个命令而对于I306我应该执行第三个命令。
1) perl -i -pe 's/:20:(.*)\r\n//g' (for Type 300)
2) perl -i -pe 's/:22:(.*)\r\n//g' (for Type 305)
3) perl -i -pe 's/:(15A|15B):(.*)\r\n//g' (for Type 306)
不知何故,我需要逐个消息地读取文件,即以^ A开头,以^ C
结束请注意,我需要使用perl命令进行inplace替换,而不是创建任何临时文件,因为我想在文件中保留很少的特殊字符。
答案 0 :(得分:5)
这是一种丰富的文件格式,但它仍然可以解析。
如果每个部分都以^C
结尾,我们可以将其用作记录分隔符 $/
,默认情况下是换行符:
use strict; use warnings;
local $/ = "-}\x03"; # ^C
while (<>) {
chomp;
...;
}
现在在该循环中,我们解析输入,例如:
# parse headers
s/\A\x01// or die "Section must start with ^A";
my ($headers, @lines) = split /\n\K/; # \Keep the newline
my %headers = $headers =~ /\G\{ ([0-9]+) : ([^\}]+) \}/xg;
# extract the type:
$headers{2} =~ /\AI([0-9]{3})/ or die "Couldn't extract type";
my $type = $1;
# depending on the type, select a filter that matches forbidden lines
my $filter = {
300 => qr/\A:20:/,
305 => qr/\A:22:/,
306 => qr/\A:15[AB]:/,
}->{$type};
$filter //= qr/(*FAIL)/; # matches never
print $headers;
# print out all lines that don't match this filter:
print for grep !/$filter/, @lines;
print "-}\x03";
此代码未经测试,但您应该能够对其进行调整。