【问题标题】:Print part of an array or a file and sort in shell打印数组或文件的一部分并在 shell 中排序
【发布时间】:2016-08-17 08:31:18
【问题描述】:

我有一个如下的文本文件

     1 : dis conn(*) type(CONN) all where(UOWLOG ne '')
AMQ8276: Display Connection details.
   CONN(AE1CA9572C47D822)                
   EXTCONN(414D51434D5147575032202020202020)
   TYPE(CONN)                            
   PID(9098)                               TID(503215) 
   APPLDESC(WebSphere MQ Channel)       
   APPLTAG(WebSphere MQ Client for Java)
   APPLTYPE(USER)                          ASTATE(NONE)
   CHANNEL(ABIS.CLIENT)           CLIENTID( )
   CONNAME(101.54.151.80)               
   CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING)
   USERID(malth)                         UOWLOG(S0599315.LOG)
   UOWSTDA(2016-08-16)                     UOWSTTI(11.06.38)
   UOWLOGDA(2016-08-16)                    UOWLOGTI(11.06.38)
   URTYPE(QMGR)                         
   EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
   QMURID(0.190537069)                     UOWSTATE(ACTIVE)
AMQ8276: Display Connection details.
   CONN(AE1CA957D787F429)                
   EXTCONN(414D51434D5147575032202020202020)
   TYPE(CONN)                            
   PID(28292)                              TID(1519092) 
   APPLDESC(WebSphere MQ Channel)       
   APPLTAG(WebSphere MQ Client for Java)
   APPLTYPE(USER)                          ASTATE(NONE)
   CHANNEL(SB.CLIENT)                  CLIENTID( )
   CONNAME(101.54.151.119)              
   CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING)
   USERID(sbp)                         UOWLOG(S0599317.LOG)
   UOWSTDA(2016-08-16)                     UOWSTTI(11.07.38)
   UOWLOGDA(2016-08-16)                    UOWLOGTI(11.07.38)
   URTYPE(QMGR)                         
   EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
   QMURID(0.190520281)                     UOWSTATE(ACTIVE)
AMQ8276: Display Connection details.
   CONN(2CC7AE57CE8E6221)                
   EXTCONN(414D51434D5147575032202020202020)
   TYPE(CONN)                            
   PID(22400)                              TID(647335) 
   APPLDESC(WebSphere MQ Channel)       
   APPLTAG(WebSphere MQ Client for Java)
   APPLTYPE(USER)                          ASTATE(NONE)
   CHANNEL(U90785.CBM.CLIENT)              CLIENTID( )
   CONNAME(101.54.163.37)               
   CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING)
   USERID(machlth)                         UOWLOG(S0599317.LOG)
   UOWSTDA(2016-08-16)                     UOWSTTI(11.07.40)
   UOWLOGDA(2016-08-16)                    UOWLOGTI(11.07.40)
   URTYPE(QMGR)                         
   EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
   QMURID(0.190574800)                     UOWSTATE(ACTIVE)
AMQ8276: Display Connection details.
   CONN(2CC7AE571BF0B721)                
   EXTCONN(414D51434D5147575032202020202020)
   TYPE(CONN)                            
   PID(22210)                              TID(1069968) 
   APPLDESC(WebSphere MQ Channel)       
   APPLTAG(WebSphere MQ Client for Java)
   APPLTYPE(USER)                          ASTATE(NONE)
   CHANNEL(APP.CLIENT)                  CLIENTID( )
   CONNAME(101.54.163.127)              
   CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING)
   USERID(apsp)                            UOWLOG(S0599317.LOG)
   UOWSTDA(2016-08-16)                     UOWSTTI(11.07.29)
   UOWLOGDA(2016-08-16)                    UOWLOGTI(11.07.29)
   URTYPE(QMGR)                         
   EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])

现在我希望我的输出显示

ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38
APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29
SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38
CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40

所以基本上,获取频道名称、conname、userid、UUOWLOG 和 UOWLOGTI,最后按 UOWLOGTI 排序。 我正在尝试在 shell 中执行此操作。

我已尝试使用awk,但似乎无法获得所需的输出。

cat UOWLOG.txt|awk -vRS="" 'BEGIN{printf ""}/\<'AMQ8276'\>/^CHANNEL{printf $0 RT}' 当我在 awk 中尝试不同的选项时出现错误。 请帮忙。

【问题讨论】:

  • 您的 awk 脚本正在使用 RS 设置来处理记录由空行分隔但在您的 smple 输入中的记录之间没有空行的情况。您的真实输入中的记录之间是否有空白 ilnes?如果是这样,请修复您的示例。我是古玩——你认为BEGIN{printf ""} 会做什么?另外,您认为AMQ8276 周围的's 会做什么? /.../^CHANNEL 怎么样?阅读 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书。

标签: bash shell awk


【解决方案1】:

所有都可以在awk 中完成,但使用一系列工具可能更容易

$ grep -oP '(CHANNEL|CONNAME|USERID|UOWLOG|UOWLOGTI)\(.*?\)' file | 
  awk -F'[()]' '{ORS=NR%5?",":RS; print $2}' | 
  sort -t, -k5

ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38
APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29
SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38
U90785.CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40

【讨论】:

  • 这行得通。我尝试插入一个 if 语句来检查 UOWLOTI 是否小于阈值,例如 11.07.00,然后打印输出。 grep -oP '(CHANNEL|CONNAME|USERID|UOWLOG|UOWLOGTI)\(.*?\)' file|awk -F'[()]' '{if($5 ge 11.07.00)ORS=NR%5?",":RS; print $2}' | sort -t, -k5 。是不是错了
  • 此时只有两个字段。另外,应该是>=。我会改为将其作为后期处理。
【解决方案2】:

我的解决方案与@karakfa 的类似,但不对字段顺序做任何假设:

$ grep -o '^\w\+:\|\w\+[(][^)]\+[)]' file |
  awk -F '[()]' -v OFS="," 'function printValues() { if ("CHANNEL" in p) { print p["CHANNEL"], p["CONNAME"], p["USERID"], p["UOWLOG"], p["UOWLOGTI"] } } /^\w+:/ { printValues(); delete p; next } { p[$1] = $2 } END { printValues() }' |
  sort -t, -k 5

我所做的是为每个“记录”创建一个关联数组,然后只打印必要的字段。

【讨论】:

    【解决方案3】:

    我的 lil 有点脏gnu awk 解决方案:

    $ awk -v RS="AMQ" 'NR>1{
    print gensub(/.*CHANNEL\(([^)]+).*CONNAME\(([^)]+).*USERID\(([^)]+).*UOWLOG\(([^)]+).*UOWLOGTI\(([^)]+).*/,"\\1,\\2,\\3,\\4,\\5","1")}' file | sort -t "," -k5
    ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38
    APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29
    SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38
    U90785.CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40
    

    【讨论】:

      【解决方案4】:

      我不知道,但接受的答案不会为“CBM.CLIENT”频道产生指定的输出,并且到目前为止所有的答案都是强烈的单行字。当转换如此复杂时,我喜欢整个脚本,所以我可以看到什么是什么。

      #! /usr/bin/awk -f 
      
      function Print() {
          OFS = ","
          print line["CHANNEL"], line["CONNAME"], line["USERID"],     \
                line["UOWLOG"], line["UOWLOGTI"]
          delete line
      }
      
      /Display Connection details[.]$/ {
          if( length(line) ) {
              Print()
          }
          next
      }
      
      $1 == "CHANNEL" {
          line[$1] = $2
          if( 3 == split( $2, channel, /[.]/ ) ) {
              line[$1] = channel[2] "." channel[3]
          }
          next
      }
      
      {
          line[$1] = $2
      }
      
      END { Print() }
      

      技术是构建所有 foo(bar) 元素的关联数组,并以明显的方式打印感兴趣的位。正则表达式很简单,输入假设也很宽松:没有字段顺序依赖性,而且格式依赖性很小。

      它依赖于一些预处理来将每个键/值对放在自己的行上,并通过后处理来对输出进行排序。调用为:

      $ cat f.sh
      #! /bin/sh
      sed -E 's/^ +//; s/ +$//g; s/  +/\
      /g'  $1 | awk -F '[:()]' -f script.awk | sort -t, -k5
      
      $ ./f.sh dat
      ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38
      APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29
      SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38
      CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40
      

      在 cmets 中,OP 提到仅打印符合特定标准的行。这很容易添加到这个Print() 函数中,以后也很容易理解。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-09
        • 1970-01-01
        • 1970-01-01
        • 2021-02-27
        • 2016-03-12
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多