Linux shell脚本将行转换为列数据

Linux shell脚本将行转换为列数据

我想从下面的输入文件转换数据,将行转换为列:

输入:

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

注意:如果每条记录之间至少有一个空行,处理起来会更容易。然后就可以以段落模式进行解析。如果您可以修改生成输入数据的任何内容来执行此操作,那么我建议您这样做。当然,如果你能做到的话,你也可以修改它来生成这种表格格式。

相关内容