행을 열 데이터로 변환하는 Linux 쉘 스크립트

행을 열 데이터로 변환하는 Linux 쉘 스크립트

다음 입력 파일의 데이터를 변환하여 행을 열로 변환하고 싶습니다.

입력하다:

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

참고: 각 레코드 사이에 빈 줄이 하나 이상 있으면 처리가 더 쉽습니다. 그런 다음 단락 모드에서 구문 분석할 수 있습니다. 이를 위해 입력 데이터를 생성하는 모든 항목을 수정할 수 있다면 그렇게 하는 것이 좋습니다. 물론 가능하다면 수정하여 이 테이블 형식을 생성할 수도 있습니다.

관련 정보