次の入力ファイルのデータを変換して行を列に変換したいと思います。
入力する:
Avamar Hostname server1.corpnet2.com
Avamar Server Version 19.1.0-38
Node Type Single Node Gen4t-M2400
Gen4T ROC SN/WWN WARNING
EMC Hardware Health PASSED
Avamar Hostname server2.CORPNET2.COM
Avamar Server Version 19.1.0-38
Node Type Single Node Gen4t-M1200
Gen4T ROC SN/WWN WARNING
EMC Hardware Health PASSED
希望の出力:
Avamar Hostname Avamar Server Version Node Type Gen4T ROC SN/WWN EMC Hardware Health
server1.corpnet2.com 19.1.0-38 Single Node Gen4t-M2400 WARNING PASSED
server2.CORPNET2.COM 19.1.0-38 Single Node Gen4t-M1200 WARNING PASSED
答え1
#!/usr/bin/perl
use strict;
my @keynames = (
'Avamar Hostname', 'Avamar Server Version','Node Type',
'Gen4T ROC SN/WWN', 'EMC Hardware Health',
);
# Make a hash where the keys are the key names, and the values
# are the index number of the key. This will make sure each
# field of every record is stored and printed in the right order.
my %keys;
foreach (0 .. $#keynames) { $keys{$keynames[$_]} = $_; };
# String field lengths are hard-coded after examining the sample data.
#
# These could be auto-calculated at the cost of having two
# passes through the data, and keeping the max length of
# each field in a hash. The hash should be initialised
# (in the foreach loop above) with the lengths of the headers
# so they're at least that wide.
my $fmt = "%-20s %-21s %-23s %-16s %-19s\n";
my @record;
printf $fmt, @keynames;
while(<>) {
chomp;
# split the input line on two-or-more spaces or a tab.
# I'm not sure if the input is tab or space separated,
# this will work with either.
my ($key,$val) = split / +|\t/;
if ($. > 1 && (eof || $key eq $keynames[0])) {
printf $fmt, @record;
@record=();
};
$record[$keys{$key}] = $val;
}
出力例:
$ ./row-to-col.pl input.txt
Avamar Hostname Avamar Server Version Node Type Gen4T ROC SN/WWN EMC Hardware Health
server1.corpnet2.com 19.1.0-38 Single Node Gen4t-M2400 WARNING PASSED
server2.CORPNET2.COM 19.1.0-38 Single Node Gen4t-M1200 WARNING PASSED
注:各レコードの間に空白行が1つ以上ある場合は、処理が簡単になります。その後、段落モードで解析できます。そのために、入力データを生成するすべての項目を変更できる場合は、そうすることをお勧めします。もちろん、可能であれば変更してこの表形式を生成することもできます。