我有要在UNIX中重新格式化的数据,以2-3列创建一个新列(在本示例中调用时),但无法计算了解如何做到这一点。在不改变列4-7的情况下,它们一起作为数据的标识符,我想在列3中列出指定次数的列2,然后输出一个值(本例中为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
所以,你想要的输出是什么? – Kenosis
@Kenosis期望的输出实际上是相同的,除了最初初始期望的输出的前四列将是一个由句点分隔的单个字段,我将使用awk重新分离(由于我是一个新手,无法真正弄清楚如何一次完成这一切) – suegene