使用以下脚本处理文件并以特定格式提供输出。 我无法制作所需的输出表。
输入
#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
use diagnostics;
my $temp_M1SLP;
my @temp_M1SLP;
my $start_run = time();
my $header = "CODE NAME DST TY DAIS NO STAT TM TMW";
print "$header\n";
open( INFILE, "<Sample1.log" ) or die "Couldn't open file M1SLP.txt\n";
while ( my $line = <INFILE> ) {
chomp($line);
@temp_M1SLP = $line;
if ( $line =~ /^\d-\d+/ ) {
$temp_M1SLP[0] = ( substr $line, 0, 14 );
$temp_M1SLP[1] = ( substr $line, 15, 7 );
$temp_M1SLP[2] = ( substr $line, 28, 5 );
$temp_M1SLP[3] = ( substr $line, 35, 4 );
printf( "%-10s", $temp_M1SLP[0] );
printf( "%-10s", $temp_M1SLP[1] );
printf( "%-8s", $temp_M1SLP[2] );
printf( "%-5s", $temp_M1SLP[3] );
}
next if ( $line =~ /^ DAIS NO STAT TM TMW/ );
{
while ( $line =~ /^\s+\w+/ ) {
$temp_M1SLP[4] = ( substr $line, 15, 15 );
$temp_M1SLP[5] = ( substr $line, 32, 4 );
$temp_M1SLP[6] = ( substr $line, 38, 14 );
$temp_M1SLP[7] = ( substr $line, 55, 7 );
$temp_M1SLP[8] = ( substr $line, 62, 5 );
printf( "%-18s", $temp_M1SLP[4] );
printf( "%-6s", $temp_M1SLP[5] );
printf( "%-8s", $temp_M1SLP[6] );
printf( "%-8s", $temp_M1SLP[7] );
printf( "%-5s", "$temp_M1SLP[8]\n" );
$line = <INFILE>;
}
}
}
my $end_run = time();
输出文件将采用此格式
CODE NAME DST TY DAIS NO STAT TM TMW
2-2017 121CM02 AVA PP EP022CM02 1 DM-ACT-AVA 10
2-2017 121CM02 AVA PP EP032CM02 1 DM-BAT-BTA 20
2-2033 119LHR AVA PP HLR3EP03203 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP080 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP090 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP110 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP100 1 DM-BAT-BTA
输入文件(Sampel1.txt)如图所示
CODE NAME DST TY
2-2017 121CM02 AVA PP
DAIS NO STAT TM TMW
EP022CM02 1 DM-ACT-AVA 10
EP032CM02 1 DM-BAT-BTA 20
2-2033 119LHR AVA PP
DAIS NO STAT TM TMW
HLR3EP03203 1 DM-BAT-BTA
2-2110 119A1AU AVA PP
DAIS NO STAT TM TMW
A1AUEP080 1 DM-BAT-BTA
A1AUEP090 1 DM-BAT-BTA
A1AUEP110 1 DM-BAT-BTA
A1AUEP100 1 DM-BAT-BTA
但是目前,我的输出结果如下。请支持检查代码并更正
CODE NAME DST TY DAIS NO STAT TM TMW
2-2017 121CM02 AVA PP EP022CM02 1 DM-ACT-AVA 10
EP032CM02 1 DM-BAT-BTA 20
2-2033 119LHR AVA PP HLR3EP03203 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP080 1 DM-BAT-BTA
A1AUEP090 1 DM-BAT-BTA
A1AUEP110 1 DM-BAT-BTA
A1AUEP100 1 DM-BAT-BTA
答案 0 :(得分:2)
我本来希望看到更多的努力来解决这个问题,特别是我不明白为什么在要求你这样做之后我必须为你格式化你的Perl代码
但是,这是一个解决方案,可以解决这个问题
#!/usr/bin/perl
use strict;
use warnings 'all';
my $header = "CODE NAME DST TY DAIS NO STAT TM TMW";
# Construct the printf format string to reproduce the header line spacing
#
my $format = do {
my @start;
push @start, $-[0] while $header =~ /\S+/g;
my @sizes = map { $start[$_+1] - $start[$_] } 0 .. $#start-1;
join("", map { "%-${_}s" } @sizes, "") . "\n";
};
printf $format, split ' ', $header;
open my $fh, '<', 'Sample1.log' or die qq{Couldn't open file "Sample1.log" for input: $!};
my @head;
while ( <$fh> ) {
# Example:
# CODE NAME DST TY
# 2-2017 121CM02 AVA PP
if (/^\d+-\d+/) {
@head = unpack 'A15 A13 A7 A*';
}
# Example:
# DAIS NO STAT TM TMW
# EP022CM02 1 DM-ACT-AVA 10
# EP032CM02 1 DM-BAT-BTA 20
elsif ( /\d/ ) {
my @tail = unpack '@15 A17 A6 A17 A7 A*';
$tail[1] += 0;
printf $format, @head, @tail;
}
}
CODE NAME DST TY DAIS NO STAT TM TMW
2-2017 121CM02 AVA PP EP022CM02 1 DM-ACT-AVA 10
2-2017 121CM02 AVA PP EP032CM02 1 DM-BAT-BTA 20
2-2033 119LHR AVA PP HLR3EP03203 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP080 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP090 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP110 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP100 1 DM-BAT-BTA
答案 1 :(得分:0)
我的解决方案首先跳过所有不相关的行。当找到以\d-\d+
开头的行(如2-2017…
)时,字段CODE,NAME,DST和TY仅在全局变量中存储。我将数组@temp_M1SLP
替换为显式变量名。
如果找到的行看起来像DAIS,NO,...(由空白后的单词标识的行),那么上一节中的值(CODE,NAME,...)和打印当前值。
我的代码或多或少是代码的混乱版本。但是,我更喜欢Borodin's solution,因为它更优雅。
#!/usr/bin/env perl
use strict;
use warnings 'all';
my $header = "CODE NAME DST TY DAIS NO STAT TM TMW";
print "$header\n";
my ( $code, $name, $dst, $ty );
open( INFILE, "<Sample1.log" ) or die "Couldn't open file Sample1.log\n";
while ( my $line = <INFILE> ) {
chomp($line);
# skip header, subheader, and empty lines:
next if ( $line =~ /^CODE\s+NAME\s+DST\s+TY/ );
next if ( $line =~ /^\s+DAIS\s+NO\s+STAT\s+TM\s+TMW/ );
next if ( $line !~ /\S/ );
# code section found? then remember the values
# but don't print them yet.
if ( $line =~ /^\d-\d+/ ) {
$code = substr( $line, 0, 14 );
$name = substr( $line, 15, 7 );
$dst = substr( $line, 28, 5 );
$ty = substr( $line, 35, 4 );
}
# line with DAIS, NO, ... found? then print the columns from
# the code section _and_ the columns of this line:
if ( $line =~ /^\s+\w+/ ) {
my $dais = substr( $line, 15, 15 );
my $no = substr( $line, 32, 4 );
my $stat = substr( $line, 38, 14 );
my $tm = substr( $line, 55, 7 );
my $tmw = substr( $line, 62, 5 );
printf( "%-10s", $code ); # from code section
printf( "%-10s", $name ); # "
printf( "%-8s", $dst ); # "
printf( "%-5s", $ty ); # "
printf( "%-18s", $dais ); # from current line
printf( "%-6s", $no ); # "
printf( "%-8s", $stat ); # "
printf( "%-8s", $tm ); # "
printf( "%-5s\n", $tmw ); # "
}
}
CODE NAME DST TY DAIS NO STAT TM TMW
2-2017 121CM02 AVA PP EP022CM02 1 DM-ACT-AVA 10
2-2017 121CM02 AVA PP EP032CM02 1 DM-BAT-BTA 20
2-2033 119LHR AVA PP HLR3EP03203 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP080 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP090 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP110 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP100 1 DM-BAT-BTA