Linux解析输出和组合线

时间:2015-12-14 07:18:16

标签: regex linux parsing awk sed

我有以下输出(在linux中):

wwn = 5001248018b6d7af  
node_wwn = 5001248018b6d7ae  
wwn = 5001248118b6d7af  
node_wwn = 5001248118b6d7ae  

我需要解析输出,看起来像这样:

50:01:24:80:18:b6:d7:ae:50:01:24:80:18:b6:d7:af
50:01:24:81:18:b6:d7:ae:50:01:24:81:18:b6:d7:af

输出是node_wwn及其wwn。

我使用一些C#应用程序完成了这项工作,但它太复杂了,无法获取输出并将其传递给程序。

string command = "cat /proc/sll/info |grep -B 9 up| grep wwn";
        string temp;
        string []commandOutput;
        string[] wwns;
        string[] wwpns;

        hbaList = new List<HBA>();

        commandOutput = (exec.RunCommand(command)).Trim().Split('\n');

        wwns = Array.FindAll(commandOutput, item => item.StartsWith("wwn = "));
        wwpns = Array.FindAll(commandOutput, item => item.StartsWith("node_wwn = "));

        for (int i =0; i<wwns.Length;i++)
        {
            hba = new HBA();

            temp = string.Format("{1}", (wwpns[i].Split('='))).Trim();
            temp += string.Format("{1}", (wwns[i].Split('='))).Trim();
            temp = Regex.Replace(temp, ".{2}", "$0:");
            temp = temp.Remove(temp.Length - 1);
            hba.ID = temp;
            hbaList.Add(hba);
        }

请帮忙......

谢谢Almog

5 个答案:

答案 0 :(得分:1)

代码编写服务,你好:)

我是用GNU awk做的。

#!/usr/bin/env awk -f

function out_wwn(wwn, node_wwn) {
    out = sprintf("%s%s", node_wwn, wwn);
    patsplit(out, a, "[0-9a-f]{2}");
    for (i = 1; i <= length(a); i++) {
        if (i > 1) printf(":");
        printf("%s", a[i]);
    }
    printf("\n");
}

/^wwn/ {wwn=$3}
/^node_wwn/ {out_wwn(wwn, $3)}

在您的情况下使用:

cat /proc/sll/info |grep -B 9 up| awk -f [the file above]

也许你也可以删除第一个grep,具体取决于你的输入。在这种情况下,你只需要做:

awk -f [the file above] < /proc/sll/info

答案 1 :(得分:1)

在这里猜一下......

awk '$1 == "wwn" { result = $3; next }
  $1 == "node_wwn" { result = $3 result; next }
   /up/ { for(i=1, sep = ""; i<length(result); sep = ":", i += 2)
        printf("%s%s", sep, substr(result, i, 2));
      printf "\n" }' /proc/sll/info

假设wwn始终位于node_wwn之前,并且在下一个输出记录之前跟up,并且空白模式是一致的。

答案 2 :(得分:0)

这是一个perl版本

while (<>) {
  if ($_ =~ /(node_)*wwn\s*=\s*(\S+)/) {
      $node = "$2$node";
      if($1 eq "node_") {
          $node =~ s/(..)(?!$)/\1:/g;
          print "$node\n";
          $node = "";
      }
   }
}

答案 3 :(得分:0)

这可能适合你(GNU sed):

 sed -r 'N;s/.* = (\S+).* = (\S+).*/\2\1/;s/..\B/&:/g' file

这会读取两行,删除残骸并重新排列数据,然后在每两个字符之间插入一个:,后跟一个非字边界。

答案 4 :(得分:0)

抛出另一个选项。

这假设node_wwn行直接跟随wwn行..

$ cat file
wwn = 5001248018b6d7af
node_wwn = 5001248018b6d7ae
wwn = 5001248118b6d7af
node_wwn = 5001248118b6d7ae

$ awk '$1=="wwn"{nf=$NF;getline;print $NF""nf}' file | perl -pe 's/\w{2}\B/$&:/g'
50:01:24:80:18:b6:d7:ae:50:01:24:80:18:b6:d7:af
50:01:24:81:18:b6:d7:ae:50:01:24:81:18:b6:d7:af