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