我有一个数据文件,如下所示:
1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3
2 4 5 8 9 10 13 17 19 29 30 32 33 50 700 800 900 950
首先,我想在每 3 个相同的值之间插入空格,通过查看第一行将每三个相同的数字放在一列中:
1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3
2 4 5 8 9 10 13 17 19 29 30 32 33 50 700 800 900 950
然后我想从第二行的每个新列中的最后一个值中减去第一个值(但如果特定列中只有一个值(此处是第二行的第四列),则前一列中的最后一个值应该从该值中减去(32-30)),同时在第一行的每一列中保留一个唯一的数字。所以最终的数据应该是这样的:
1 1 1 2 2 3 3
3 2 4 11 2 667 150
请问有什么建议吗?同时我应该提到我的真实数据确实很大,我想将第一行的每 5 个唯一值分组。我可能想改变小组的规模。所以我需要脚本灵活..
答案1
Perl 来救援!
#!/usr/bin/perl
use warnings;
use strict;
my $group_size = 3;
my @first = split ' ', <>;
my @groups;
my $start_index = 0;
while ($start_index < @first) {
my $step = 1;
while ( $step < $group_size
&& $start_index + $step < @first
&& $first[$start_index] == $first[ $start_index + $step ]
) {
++$step;
}
push @groups, $step;
print $first[$start_index], ' ';
$start_index += $step;
}
print "\n";
my @numbers = split ' ', <>;
my $last;
for my $size (@groups) {
my @group = splice @numbers, 0, $size;
my $value = $group[-1] - $group[0];
$value = $group[0] - $last if 1 == $size;
$last = $group[-1];
print $value, ' ';
}
print "\n";
您尚未指定如果第一个组只有一个成员时会发生什么。
答案2
这与 choroba 的答案类似
$ cat file
1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3
2 4 5 8 9 10 13 17 19 29 30 32 33 50 700 800 900 950
$ perl -ane '
if ($. == 1) {
for (($n,$i,$j) = (1,0,0); $j < @F; $n++, $j++) {
if ($n == 3 || $F[$j] != $F[$j+1]) {
$i-- if $i == $j;
push @pairs, [$i, $j];
$n = 0;
$i = $j + 1;
}
}
printf "%d ", $F[ $_->[1] ] for @pairs;
}
else {
printf "%d ", $F[ $_->[1] ] - $F[ $_->[0] ] for @pairs;
}
print "\n";
' < file
1 1 1 2 2 3 3
3 2 4 11 2 667 150
对于输入的第一行,($. == 1)
它计算您感兴趣的索引对的列表。这可以得出:
[[0, 2], [3, 5], [6, 7], [8, 10], [10, 11], [12, 14], [15, 17]]