다음과 같은 데이터 파일이 있습니다.
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개마다 사이에 공백을 삽입하고 첫 번째 행을 보고 동일한 숫자 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
이것은 초로바의 답변과 유사합니다
$ 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]]