Reformat multi-line records in perl

时间:2015-04-24 21:31:29

标签: perl

I have a commandoutput and want to extract some lines from it and join them based on some condition. I am opening a file handle for the command output. Below is the sample data.

 array I (SAS, Unused Space: 0  MB)


      logicaldrive 9 (931.5 GB, RAID 1, OK)

      physicaldrive 6C:3:1 (port 6C:box 3:bay 1, SAS, 1 TB, OK)
      physicaldrive 6C:3:2 (port 6C:box 3:bay 2, SAS, 1 TB, OK)
 array K (SAS, Unused Space: 0  MB)


      logicaldrive 11 (931.5 GB, RAID 1, OK)

      physicaldrive 7C:3:5 (port 7C:box 3:bay 5, SAS, 1 TB, OK)
      physicaldrive 7C:3:6 (port 7C:box 3:bay 6, SAS, 1 TB, OK)

   unassigned

      physicaldrive 7C:3:7 (port 7C:box 3:bay 7, SAS, 1 TB, OK)
      physicaldrive 7C:3:8 (port 7C:box 3:bay 8, SAS, 1 TB, OK)

 array L (SAS, Unused Space: 0  MB)


      logicaldrive 12 (931.5 GB, RAID 1, OK)

      physicaldrive 8C:3:5 (port 8C:box 3:bay 5, SAS, 1 TB, OK)
      physicaldrive 8C:3:6 (port 8C:box 3:bay 6, SAS, 1 TB, OK)

What I'm trying to do is:

  1. Remove the Line containing unassigned and the Physical drives associated with it. The physical drives in this case is 2 , But could be 3 or more lines .

  2. Join lines containing array and the physical drives.

The output should be something like this:

array I (SAS, Unused Space: 0  MB) physicaldrive 6C:3:1 (port 6C:box 3:bay 1, SAS, 1 TB, OK) physicaldrive 6C:3:2 (port 6C:box 3:bay 2, SAS, 1 TB, OK)

array K (SAS, Unused Space: 0  MB) physicaldrive 7C:3:5 (port 7C:box 3:bay 5, SAS, 1 TB, OK) physicaldrive 7C:3:6 (port 7C:box 3:bay 6, SAS, 1 TB, OK)

As said: In this case each Physical drive might have only 2 drives, but the script should work for even more lines containing Physical drives after array.


Below is exactly the Lines of I/P from the Command .

Smart Array P410i in Slot 0 (Embedded) (sn: 500143802128A270)

  array A (SAS, Unused Space: 0  MB)


  logicaldrive 1 (931.5 GB, RAID 1, OK)

  physicaldrive 2C:1:1 (port 2C:box 1:bay 1, SAS, 1 TB, OK)
  physicaldrive 2C:1:2 (port 2C:box 1:bay 2, SAS, 1 TB, OK)

array B (SAS, Unused Space: 0 MB)

  logicaldrive 2 (931.5 GB, RAID 1, OK)

  physicaldrive 2C:1:3 (port 2C:box 1:bay 3, SAS, 1 TB, OK)
  physicaldrive 2C:1:4 (port 2C:box 1:bay 4, SAS, 1 TB, OK)

array C (SAS, Unused Space: 0 MB)

  logicaldrive 3 (931.5 GB, RAID 1, OK)

  physicaldrive 3C:1:5 (port 3C:box 1:bay 5, SAS, 1 TB, OK)
  physicaldrive 3C:1:6 (port 3C:box 1:bay 6, SAS, 1 TB, OK)

array D (SAS, Unused Space: 0 MB)

  logicaldrive 4 (931.5 GB, RAID 1, OK)

  physicaldrive 3C:1:7 (port 3C:box 1:bay 7, SAS, 1 TB, OK)
  physicaldrive 3C:1:8 (port 3C:box 1:bay 8, SAS, 1 TB, OK)

array E (SAS, Unused Space: 0 MB)

  logicaldrive 5 (931.5 GB, RAID 1, OK)

  physicaldrive 4C:2:1 (port 4C:box 2:bay 1, SAS, 1 TB, OK)
  physicaldrive 4C:2:2 (port 4C:box 2:bay 2, SAS, 1 TB, OK)

array F (SAS, Unused Space: 0 MB)

  logicaldrive 6 (931.5 GB, RAID 1, OK)

  physicaldrive 4C:2:3 (port 4C:box 2:bay 3, SAS, 1 TB, OK)
  physicaldrive 4C:2:4 (port 4C:box 2:bay 4, SAS, 1 TB, OK)

array G (SAS, Unused Space: 0 MB)

  logicaldrive 7 (931.5 GB, RAID 1, OK)

  physicaldrive 5C:2:5 (port 5C:box 2:bay 5, SAS, 1 TB, OK)
  physicaldrive 5C:2:6 (port 5C:box 2:bay 6, SAS, 1 TB, OK)

array H (SAS, Unused Space: 0 MB)

  logicaldrive 8 (931.5 GB, RAID 1, OK)

  physicaldrive 5C:2:7 (port 5C:box 2:bay 7, SAS, 1 TB, OK)
  physicaldrive 5C:2:8 (port 5C:box 2:bay 8, SAS, 1 TB, OK)

array I (SAS, Unused Space: 0 MB)

  logicaldrive 9 (931.5 GB, RAID 1, OK)

  physicaldrive 6C:3:1 (port 6C:box 3:bay 1, SAS, 1 TB, OK)
  physicaldrive 6C:3:2 (port 6C:box 3:bay 2, SAS, 1 TB, OK)

array J (SAS, Unused Space: 0 MB)

  logicaldrive 10 (931.5 GB, RAID 1, OK)

  physicaldrive 6C:3:3 (port 6C:box 3:bay 3, SAS, 1 TB, OK)
  physicaldrive 6C:3:4 (port 6C:box 3:bay 4, SAS, 1 TB, OK)

array K (SAS, Unused Space: 0 MB)

  logicaldrive 11 (931.5 GB, RAID 1, OK)

  physicaldrive 7C:3:5 (port 7C:box 3:bay 5, SAS, 1 TB, OK)
  physicaldrive 7C:3:6 (port 7C:box 3:bay 6, SAS, 1 TB, OK)

unassigned

  physicaldrive 7C:3:7 (port 7C:box 3:bay 7, SAS, 1 TB, OK)
  physicaldrive 7C:3:8 (port 7C:box 3:bay 8, SAS, 1 TB, OK)

Enclosure SEP (Vendor ID HP, Model HP SAS EXP Card) 248 (WWID: 5001438020B5CC65, Box: 3)

Expander 250 (WWID: 5001438020B5CC66, Box: 1)

SEP (Vendor ID PMCSIERA, Model SRC 8x6G) 249 (WWID: 500143802128A27F)

2 个答案:

答案 0 :(得分:0)

您可以采取的一种方法 - 也是第一种方法 - 是在perl $/中设置记录分隔符,并使用正则表达式处理每个记录

这样的事情可能是:

#!/usr/bin/env perl
use strict;
use warnings;

#set record separator to linefeed followed by word array. 
#if this is the only place "array" occurs, then the linefeed is superfluous. 
local $/ = "\narray";

while ( <DATA> ) {
   #remove the word 'array'. 
   s/\s*array\s*//g;
   #delete anything after 'unassigned' in this array. 
   s/unassigned.*//gms;
   #remove the 'logicaldrive' lines. 
   s/.*logicaldrive.*//g;
   #delete all linefeeds in this record
   s,\n,,gms;
   #tidy up some of the spaces.
   s,\s+, ,g;
   s,^\s*,,g;
   #print this record. 
   print;
   print "\n";
}

__DATA__
array I (SAS, Unused Space: 0  MB)


      logicaldrive 9 (931.5 GB, RAID 1, OK)

      physicaldrive 6C:3:1 (port 6C:box 3:bay 1, SAS, 1 TB, OK)
      physicaldrive 6C:3:2 (port 6C:box 3:bay 2, SAS, 1 TB, OK)

array K (SAS, Unused Space: 0  MB)


      logicaldrive 11 (931.5 GB, RAID 1, OK)

      physicaldrive 7C:3:5 (port 7C:box 3:bay 5, SAS, 1 TB, OK)
      physicaldrive 7C:3:6 (port 7C:box 3:bay 6, SAS, 1 TB, OK)

   unassigned

      physicaldrive 7C:3:7 (port 7C:box 3:bay 7, SAS, 1 TB, OK)
      physicaldrive 7C:3:8 (port 7C:box 3:bay 8, SAS, 1 TB, OK)

array L (SAS, Unused Space: 0  MB)


      logicaldrive 12 (931.5 GB, RAID 1, OK)

      physicaldrive 8C:3:5 (port 8C:box 3:bay 5, SAS, 1 TB, OK)
      physicaldrive 8C:3:6 (port 8C:box 3:bay 6, SAS, 1 TB, OK)

答案 1 :(得分:0)

以下是我正在尝试的代码。

<font color='green'>text</font>