Perl:读取文件并重新排列成列

时间:2015-01-15 12:11:22

标签: perl file-io

我有一个我想阅读的文件,其中包含以下结构:

编辑:我让这个例子更加具体,以澄清我的需要

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新手。有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:1)

我只使用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.
}

答案 1 :(得分:1)

使用范围运算符可以非常简单。表达式

/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
相关问题