这是我文件中的示例行:
42001232 2011-07-01 51 100001 0 100002 0 2011-07-02 51 100003 0 100004 0
如何安排它看起来像这样
42001232 2011-07-01 51 100001 0
42001232 2011-07-01 51 100002 0
42001232 2011-07-02 51 100003 0
42001232 2011-07-02 51 100004 0
除第一列外,所有列都以日期开头重复。 我需要以表格形式组织它。此外,这里的分隔符是TAB。
答案 0 :(得分:1)
这是使用awk
的一种方式。像:
awk -f script.awk file
script.awk
的内容:
BEGIN {
FS=OFS="\t"
}
{
for(i=2;i<=NF;i++) {
if ($i ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) {
for (j=i+2;j<=NF;j+=2) {
if ($j ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) {
break
}
else {
print $1, $i, $(i+1), $j, $(j+1)
}
}
}
}
}
结果:
42001232 2011-07-01 51 100001 0
42001232 2011-07-01 51 100002 0
42001232 2011-07-02 51 100003 0
42001232 2011-07-02 51 100004 0
或者,这是单行:
awk 'BEGIN { FS=OFS="\t" } { for(i=2;i<=NF;i++) if ($i ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) for (j=i+2;j<=NF;j+=2) if ($j ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) break; else print $1, $i, $(i+1), $j, $(j+1) }' file
答案 1 :(得分:0)
这适用于给定的数据:
#!/usr/bin/env perl
use strict;
use warnings;
use English qw( -no_match_vars );
$OFS = qq"\t";
while (<>)
{
chomp;
my(@fields) = split /\s+/, $_;
my $col1 = shift @fields;
my $date = shift @fields;
my $col3 = shift @fields;
while (scalar(@fields) > 1)
{
if ($fields[0] =~ /^\d{4}-\d\d-\d\d$/)
{
$date = shift @fields;
$col3 = shift @fields;
next;
}
else
{
my $col4 = shift @fields;
my $col5 = shift @fields;
print $col1, $date, $col3, $col4, "$col5\n";
}
}
print STDERR "oops - debris $fields[0] left over\n" if (scalar(@fields) != 0);
}
我得到的输出是:
42001232 2011-07-01 51 100001 0
42001232 2011-07-01 51 100002 0
42001232 2011-07-02 51 100003 0
42001232 2011-07-02 51 100004 0
这是一个非常可怕的格式,必须解析。我必须对处理重复的方式做一些假设,以便日期之后的列固定到下一个日期,例如。