我有要在 unix 中重新格式化的数据,将第 2-3 列创建一个新列(在示例中称为 when ),但在弄清楚如何执行此操作时遇到了麻烦。在不更改作为数据标识符的第 4-7 列的情况下,我想打印第 2 列的第 3 列中指定的次数,然后打印一个值(在本例中为 31)N(= 每个标识符的第 1 列) 减去(每个标识符第 3 列的总和)次数。因此,重新格式化的数据对于每个标识符将总共有 N 行。开始的数据如下所示:
N time awake line sex temp rep
9 15 1 188 f 25 1
9 20 1 188 f 25 1
9 21 1 188 f 25 1
9 28 1 188 f 25 1
10 12 1 205 m 25 1
10 14 3 205 m 25 1
10 16 1 205 m 25 1
10 18 1 205 m 25 1
10 19 2 205 m 25 1
10 22 1 205 m 25 1
10 24 1 205 m 25 1
重新格式化的数据应该看起来像这样:
line sex temp rep when
188 f 25 1 15
188 f 25 1 20
188 f 25 1 21
188 f 25 1 28
188 f 25 1 31
188 f 25 1 31
188 f 25 1 31
188 f 25 1 31
188 f 25 1 31
205 m 25 1 12
205 m 25 1 14
205 m 25 1 14
205 m 25 1 14
205 m 25 1 16
205 m 25 1 18
205 m 25 1 19
205 m 25 1 19
205 m 25 1 22
205 m 25 1 24
我的猜测是它需要某种循环,我认为伪代码看起来像这样:
for (each columns 4-7)
tot = (column 1)
rem = tot - sum (column 3)
for (i=0; i <= column 3; i++)
print column 2"\n"
for (j=0; i <= rem; j++)
print "31\n"
任何帮助深表感谢!
编辑添加:我尝试从下面的@mvp 修改 perl 代码,但它不太正确。我使用 awk 将原始列 4-7 重新格式化为一个名为 id 的字段(和变量)。任何意见?
print "id when\n"; # output header
my $temp='188.f.25.1';
my $count;
my $rest;
my $total;
while(my $input = <>) {
my ($n, $time, $awake, $id)
= split /\s+/, $input; # read each line
next if $n eq 'N'; # skip input header line
if ($id eq $temp) {
$count++;
for (1..$awake) {print "$id $time\n";}
$total = $n;
next;
}
else {
$rest=$total-$count;
for (1..$rest) {print "$temp 31\n";}
}
$count=0;
$temp = $id;
next;
}
以及修改后的输入文件:
N time awake line.sex.temp.rep
9 15 1 188.f.25.1
9 20 1 188.f.25.1
9 21 1 188.f.25.1
9 28 1 188.f.25.1
10 12 1 205.m.25.1
10 14 3 205.m.25.1
10 16 1 205.m.25.1
10 18 1 205.m.25.1
10 19 2 205.m.25.1
10 22 1 205.m.25.1
10 24 1 205.m.25.1
10 10 1 206.m.25.1
10 14 1 206.m.25.1
10 18 1 206.m.25.1
10 20 1 206.m.25.1
10 24 1 206.m.25.1
10 26 1 206.m.25.1
10 27 1 206.m.25.1
10 28 2 206.m.25.1