誰かが複数の列を行に変換することに関して私と同様の質問をしました。ただし、私が作業している特定の列の形式は少し異なります。私のファイルには以下が含まれているからです。変える時には重複した列番号がある場合があります。
たとえば、
100
1
2
3
200 300
1 1
2 2
3 3
100
1
2
3
400 500 600 700 800 900
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
100 400 700
1 1 1
2 2 2
3 3 3
この列を次の行に置き換えたいと思います。
100 1 2 3
200 1 2 3
300 1 2 3
100 1 2 3
400 1 2 3
500 1 2 3
600 1 2 3
700 1 2 3
800 1 2 3
900 1 2 3
100 1 2 3
400 1 2 3
700 1 2 3
次に、次のように、最初の列の値に基づいて行をソートします。
100 1 2 3
100 1 2 3
100 1 2 3
200 1 2 3
300 1 2 3
400 1 2 3
400 1 2 3
500 1 2 3
600 1 2 3
700 1 2 3
700 1 2 3
800 1 2 3
900 1 2 3
そして、次のように重複行の値を合計します。
100 3 6 9
200 1 2 3
300 1 2 3
400 2 4 6
500 1 2 3
600 1 2 3
700 2 4 6
800 1 2 3
900 1 2 3
100行、400行、700行に重複があるため、対応する列値が合計されたことがわかります。
どんな洞察力や提案でも大変感謝いたします。
答え1
私はこれにPerlの短絡モードを使います:
#!/usr/bin/env perl
use strict;
use warnings;
my %final_lines; # Data structure to hold the modified lines
my $filename = shift // die "No input file given!\n";
open my $IN,'<',$filename or die "Failed to open $filename for input: $!\n";
PARAGRAPH: {
local $/=""; # Paragraph mode
while(<$IN>){ # Read a new "paragraph"
my @lines = split /\n/;
my @fields = split /\s+/,(shift @lines);
my $line_number =0;
for my $line (@lines){
my @data = split /\s+/,$line;
map {
$final_lines{$fields[$_]}->[$line_number] += $data[$_]
} (0..$#data);
$line_number++;
}
}
}
for my $key (sort { $a <=> $b } keys %final_lines){
local $,=' ';
print STDOUT $key,@{$final_lines{$key}};
print STDOUT "\n";
}
次のように使用してください。
$ /path/to/script input_file > output_file
このコードはテストされ、正常に動作します。 @cjmがコメントで指摘したように、入力ファイルが大きい場合は時間がかかることがあります。最も時間がかかる可能性が最も高いステップが最後のsort
鍵です。