Perl:读取文件并重新排列成列
Perl: read file and re-arrange into columns
我有一个我想阅读的文件,它具有以下结构:
编辑:我让这个例子更具体一些来阐明我需要什么
HEADER
MORE HEADER
POINTS 2
x1 y1 z1
x2 y2 z2
VECTORS velocities
u1 v1 w1
u2 v2 w2
VECTORS displacements
a1 b1 c1
a2 b2 c2
包含一些数据的块的数量是任意的,它们的顺序也是如此。
我只想读取 "POINTS" 和 "VECTORS displacements" 下的数据,并按以下格式重新排列它们:
x1 y1 z1 a1 b1 c1
x2 y2 z2 a2 b2 c2
我设法将 xyz 和 abc 块读取到单独的数组中,但我的问题是将它们合并为一个。
我应该提到我是一个 perl 新手。有人可以帮助我吗?
我只用了 1 个数组来记住前 3 列。处理第二部分数据时可以直接输出
#!/usr/bin/perl
use strict;
use warnings;
my @first; # To store the first 3 columns.
my $reading; # Flag: are we reading the data?
while (<>) {
next unless $reading or /DATA-TO-READ/; # Skip the header.
$reading = 1, next unless $reading; # Skip the DATA-TO-READ line, enter the
# reading mode.
last if /DATA-NOT-TO-READ/; # End of the first part.
chomp; # Remove a newline.
push @first, $_; # Remember the line.
}
undef $reading; # Restore the flag.
while (<>) {
next unless $reading or /DATA-TO-READ/;
$reading = 1, next unless $reading;
last if /DATA-NOT-TO-READ/;
print shift @first, " $_"; # Print the remembered columns + current line.
}
使用范围运算符,这变得非常简单。表达式
/DATA-TO-READ/ .. /DATA-NOT-TO-READ/
在范围的第一行(DATA-TO-READ
行)计算为 1,在第二行计算为 2,等等。在最后一行(DATA-NOT-TO-READ
行)E0
是附加到计数,以便它评估为相同的数值,但也可以测试是否是最后一行。在范围外的行上,它的计算结果为 false 值。
这个程序累积数组@output
中的数据,并在到达输入末尾时打印它。它期望输入文件的路径作为命令行上的参数。
use strict;
use warnings;
my (@output, $i);
while (<>) {
my $index = /DATA-TO-READ/ .. /DATA-NOT-TO-READ/;
if ($index and $index > 1 and $index !~ /E/) {
push @{ $output[$index-2] }, split;
}
}
print "@$_\n" for @output;
输出
x1 y1 z1 a1 b1 c1
x2 y2 z2 a2 b2 c2
我有一个我想阅读的文件,它具有以下结构:
编辑:我让这个例子更具体一些来阐明我需要什么
HEADER
MORE HEADER
POINTS 2
x1 y1 z1
x2 y2 z2
VECTORS velocities
u1 v1 w1
u2 v2 w2
VECTORS displacements
a1 b1 c1
a2 b2 c2
包含一些数据的块的数量是任意的,它们的顺序也是如此。
我只想读取 "POINTS" 和 "VECTORS displacements" 下的数据,并按以下格式重新排列它们:
x1 y1 z1 a1 b1 c1
x2 y2 z2 a2 b2 c2
我设法将 xyz 和 abc 块读取到单独的数组中,但我的问题是将它们合并为一个。
我应该提到我是一个 perl 新手。有人可以帮助我吗?
我只用了 1 个数组来记住前 3 列。处理第二部分数据时可以直接输出
#!/usr/bin/perl
use strict;
use warnings;
my @first; # To store the first 3 columns.
my $reading; # Flag: are we reading the data?
while (<>) {
next unless $reading or /DATA-TO-READ/; # Skip the header.
$reading = 1, next unless $reading; # Skip the DATA-TO-READ line, enter the
# reading mode.
last if /DATA-NOT-TO-READ/; # End of the first part.
chomp; # Remove a newline.
push @first, $_; # Remember the line.
}
undef $reading; # Restore the flag.
while (<>) {
next unless $reading or /DATA-TO-READ/;
$reading = 1, next unless $reading;
last if /DATA-NOT-TO-READ/;
print shift @first, " $_"; # Print the remembered columns + current line.
}
使用范围运算符,这变得非常简单。表达式
/DATA-TO-READ/ .. /DATA-NOT-TO-READ/
在范围的第一行(DATA-TO-READ
行)计算为 1,在第二行计算为 2,等等。在最后一行(DATA-NOT-TO-READ
行)E0
是附加到计数,以便它评估为相同的数值,但也可以测试是否是最后一行。在范围外的行上,它的计算结果为 false 值。
这个程序累积数组@output
中的数据,并在到达输入末尾时打印它。它期望输入文件的路径作为命令行上的参数。
use strict;
use warnings;
my (@output, $i);
while (<>) {
my $index = /DATA-TO-READ/ .. /DATA-NOT-TO-READ/;
if ($index and $index > 1 and $index !~ /E/) {
push @{ $output[$index-2] }, split;
}
}
print "@$_\n" for @output;
输出
x1 y1 z1 a1 b1 c1
x2 y2 z2 a2 b2 c2