【问题标题】:Linux Parsing Output and Combine LinesLinux 解析输出和合并行
【发布时间】:2016-03-19 14:42:43
【问题描述】:

我有以下输出(在 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);
        }

请帮忙...

感谢阿尔莫格

【问题讨论】:

  • 发布你的尝试..
  • 发表感谢,,,我不熟悉 sed 和 awk 等 linux 解析命令...请帮助
  • 你为什么使用grep -B9?还有哪些您没有向我们展示的其他输出?整个任务可以通过单个 Awk 脚本轻松处理,但我们需要了解预期的输入。

标签: regex linux parsing awk sed


【解决方案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

【讨论】:

  • @almog50 感谢我的支持和验证 ;)
  • cat,正如您所注意到的,grep 也可能是 useless
【解决方案2】:

在这里猜一猜……

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 之后,并且空白模式是一致的。

【讨论】:

    【解决方案3】:

    这是一个 perl 版本

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

    【讨论】:

      【解决方案4】:

      这可能对你有用(GNU sed):

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

      这一次读取两行,删除杂乱无章并重新排列数据,然后在每两个字符之间插入一个:,后跟一个非单词边界。

      【讨论】:

        【解决方案5】:

        只是抛出另一个选项。

        这假设 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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-13
          相关资源
          最近更新 更多