以下の内容を含む大容量ファイルがあります。
Quantity 20589
Quantity 12297
Quantity 100346
Quantity 0
Quantity 141999
Quantity 23662
Quantity 551071
Quantity 72917
Quantity 60460
Quantity 19712
Quantity 35530
Quantity 0
Quantity 29818
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Price 0
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
Discount 100
このファイルから新しいファイルを作成したいと思います。そのファイルのデータは次のようになります。
Quantity,Price,Discount
20589,0,100
12297,0,100
100346,0,100
0,0,100
141999,0,100
23662,0,100
551071,0,100
72917,0,100
60460,0,100
19712,0,100
35530,0,100
0,0,100
29818,0,100
つまり、元のファイルを読み取るとき、列名は新しいファイルのヘッダーと上記の対応する値でなければなりません。
シェルスクリプトを使用して新しいファイルを作成するのに役立ちます。
答え1
すべてのデータを含む大規模な配列を構築すると、単一のコマンド内ですべての操作を実行できますが、awk
ファイルが大きい場合に使用可能なメモリの問題が発生する可能性があります。そのため、いくつかのステップを経てこれを行います。
header=$(awk '{print $1}' file | uniq | tr '\n' ',')
printf "${header%?}\n" > output
paste -d, <(awk '$1=="Quantity"{print $2}' file) \
<(awk '$1=="Price"{print $2}' file) \
<(awk '$1=="Discount"{print $2}' file) >> output
ここで唯一のトリッキーな部分は、タイトルの最後の最後のカンマを削除することです。私は${par%?}
これにコンストラクタを使用しました。
答え2
Perlでは、このように使用できます。
#!/usr/bin/perl
use strict;
use warnings;
my $file=$ARGV[0];
open my $fId, '<', $file or die "Error opeining file <$file>.";
my @qty = ();
my @price = ();
my @discount = ();
while(<$fId>){
chomp;
my @fields = split (/\t/, $_);
push @qty , $fields[1] if $fields[0] =~ m/Quantity/;
push @price , $fields[1] if $fields[0] =~ m/Price/;
push @discount , $fields[1] if $fields[0] =~ m/Discount/;
}
close $fId;
print "Quantity,Price,Discount\n";
for(my $i = 0; $i < scalar @qty; $i++){
print "$qty[$i],$price[$i],$discount[$i]\n";
}
ファイル名をパラメータとして渡す必要があります。
例: ./test.pl input_file