簡體   English   中英

UNIX(AIX)腳本,僅使用awk或其他文件處理實用程序處理文件

[英]UNIX(AIX) script to process a file using only awk or other file processing utilities

我有一個任務是編寫一個腳本來過濾MQ runmqsc命令的輸入並將輸出重定向到另一個文件。 我一直在努力使用許多其他Linux命令管道,它似乎在Linux中工作得很好,但我的經理需要在AIX系統上運行腳本,所以UNIX操作系統。 我意識到許多在Linux上運行良好或在Linux中完成工作的命令將在UNIX或基於UNIX的系統上產生完全不同的輸出。 runmqsc命令的輸出如下所示:

5724-H72 (C) Copyright IBM Corp. 1994, 2009.  ALL RIGHTS RESERVED.
Starting MQSC for queue manager CNUMQ02B.


     1 : DISPLAY QLOCAL(*) CURDEPTH
AMQ8409: Display Queue details.
   QUEUE(ADEXA.AOM.REPLY.MR.QL)            TYPE(QLOCAL)
   CURDEPTH(0)                          
AMQ8409: Display Queue details.
   QUEUE(ADEXA.AOM.REPLY.QL)               TYPE(QLOCAL)
   CURDEPTH(0)                          
AMQ8409: Display Queue details.
   QUEUE(ADEXA.ERROR.QL)                   TYPE(QLOCAL)
   CURDEPTH(0)                          
AMQ8409: Display Queue details.
   QUEUE(ADEXA.FACT.OUT.QL)                TYPE(QLOCAL)
   CURDEPTH(0)
AMQ8409: Display Queue details.
   QUEUE(ADW.REMAN.XREF.ERR.QL)            TYPE(QLOCAL)
   CURDEPTH(14)
AMQ8409: Display Queue details.
   QUEUE(SAPNA.MESS.CRITICAL.CLASS.RESUME.QL)
   TYPE(QLOCAL)                            CURDEPTH(123)
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.

我基本上需要做的只是顯示隊列的名稱,空格,然后是同一行上的隊列深度,沒有尾隨空格,文件的開頭或結尾沒有換行符,因此它將類似於以空格作為分隔符的csv文件。 我還需要過濾掉隊列深度等於0的隊列,因此輸出將如下所示:

ADW.REMAN.XREF.ERR.QL 14

正如我所說,我在Linux上嘗試了很多命令,但是我對UNIX和Linux上的命令和標志實際上大致相同有所了解,並且我的經理今天想要這個,所以如果你有機會讀到這個我要求你至少指導我使用什么來嘗試解決它:)謝謝。

這是我在Linux中寫的:

head -n -3 "$1" | 
tail -n +6 | 
sed '/AMQ8409: Display Queue details./d' | 
sed 's/TYPE(QLOCAL)//g' | 
tr -d ' \t\r\f' | 
awk 'NR%2{printf "%s ",$0;next;}1' | 
sed '/CURDEPTH(0)/d' | 
awk '{gsub(/QUEUE(/, ""); gsub(/CURDEPTH(/, ""); gsub(/)/, ""); print}' |
sort -nk2 

試試這個更簡單的命令..

sed -n -e 's/.*QUEUE(\([^)]*\)).*/\1/p' -e 's/.*CURDEPTH(\([0-9]*\)).*/\1/p' \
   | paste -d ' ' - - \
   | grep -v ' 0$'
$ awk '/QUEUE|CURDEPTH\(/ {                            # on matching records
           gsub(/^[^(]+\(|).*$/,"");                   # remove unwanted parts
           printf "%s%s", $0, ($0~/^[0-9]+$/?ORS:OFS)  # print ORS after depth
       }' file
ADEXA.AOM.REPLY.MR.QL 0
ADEXA.AOM.REPLY.QL 0
ADEXA.ERROR.QL 0
ADEXA.FACT.OUT.QL 0
ADW.REMAN.XREF.ERR.QL 14

這是一個不使用gsub

awk -F "[()]" '/QUEUE/ {quename=$2} /CURDEPTH\(/ {print quename, $2} '

而不是使用“head”和“tail”和“sed”來刪除不需要的行,而是使用grep來獲取你想要的那些。 我不確定哪些選項可以在AIX上運行,但是我應該相信它們。

grep -B 1 CURDEPTH $1
grep -A 1 QUEUE $1
grep -e QUEUE -e CURDEPTH $1

接下來,加入並格式化這些行:

sed 's#.*QUEUE(\([^)]*\)).*\n.*CURDEPTH(\([0-9]*\)).*#\1 \2#'

如果這不能正常工作,請嘗試使用'\\ r'而不是'\\ n'。

最后,刪除深度為0的所有行(2個選項):

grep -v " 0$"
sed '# 0$#d'

我對這種形式的sed不太熟悉 - 我從你的代碼示例中捏了一下 - 但它看起來很簡單所以應該工作。

所有這些命令都是您可以獲得的最基本的形式,因此應該在任何* nix系統上都能正常工作。 希望。 最初的grep和sed是風險的最高點。

這在AIX上適用於獲取所需的輸出,這使用IBM MQ的WHERE子句將輸出限制為CURDEPTH大於0的隊列:

echo "DIS QL(*) WHERE(CURDEPTH GT 0)" | runmqsc <qmgr> | sed -e 's/\((.*)\)  *\(.*\)/\1\
\2/g' -e 's/^ *\([A-Z][A-Z]*[(][^)][^)]*[)]\)/\1/g' -e 's/^\(AMQ[0-9][0-9]*:\).*$/\1/g' | awk -F '[()]' -v OFS=" " 'function printValues() { if ("QUEUE" in p) { print p["QUEUE"], p["CURDEPTH"] } } /AMQ8409:/ { printValues(); for (i in p) { delete p[i] }; next } { p[$1] = $2 } END { printValues() }'

請注意,上面是兩行,第一行末尾的\\允許sed命令替換為嵌入的新行。 awk printValues語法來自@ mike.dld回答這篇文章“ 打印數組或文件的一部分並在shell中排序 ”。 因為AIX awk不支持其他語法,我不得不用for (i in p) { delete p[i] }替換他的delete p

如果要使用文件作為輸入運行,請使用以下命令:

cat file | sed -e 's/\((.*)\)  *\(.*\)/\1\
\2/g' -e 's/^ *\([A-Z][A-Z]*[(][^)][^)]*[)]\)/\1/g' -e 's/^\(AMQ[0-9][0-9]*:\).*$/\1/g' | awk -F '[()]' -v OFS=" " 'function printValues() { if ("QUEUE" in p) { print p["QUEUE"], p["CURDEPTH"] } } /AMQ8409:/ { printValues(); for (i in p) { delete p[i] }; next } { p[$1] = $2 } END { printValues() }' | grep -v ' 0$'

可以輕松地向輸出添加任意數量的屬性。 如果你想在將來擴展它,你只需要為awk命令添加更多條目,用於所需的每個屬性: , p["ATTR1"], p["ATTR2"]

MAXDEPTH為例:

echo "DIS QL(*) WHERE(CURDEPTH GT 0)" | runmqsc <qmgr> | sed -e 's/\((.*)\)  *\(.*\)/\1\
\2/g' -e 's/^ *\([A-Z][A-Z]*[(][^)][^)]*[)]\)/\1/g' -e 's/^\(AMQ[0-9][0-9]*:\).*$/\1/g' | awk -F '[()]' -v OFS=" " 'function printValues() { if ("QUEUE" in p) { print p["QUEUE"], p["CURDEPTH"], p["MAXDEPTH"] } } /AMQ8409:/ { printValues(); for (i in p) { delete p[i] }; next } { p[$1] = $2 } END { printValues() }'

請注意,如果屬性本身具有嵌入式括號,則此答案和其他可能存在問題,這在隊列的DESCR字段中是可能的,並且對於其他對象類型上的各種其他字段也是如此。 一個常見的例子是CHANNELCONNAME屬性。 CONNAME使用格式hostname(port)因此顯示為CONNAME(hostname(port))

使用awk ,可以相對容易地完成:

runmqsc "display qlocal(*) curdepth" | awk '
    /QUEUE\(/ {
        gsub(/^[^\(]*\(/, "", $0);
        gsub(/\).*$/, "", $0);
        qname = $0;
    }
    /CURDEPTH\(/ {
        gsub(/^[^\(]*\(/, "", $0);
        gsub(/\).*$/, "", $0);
        print qname" "$0;
    }'

這基本上只是從包含QUEUE(行中提取隊列名稱QUEUE(並將其存儲以供日后使用)。

當它找到包含CURDEPTH(它以相同的方式提取深度,然后輸出與存儲的隊列名稱一起)。

每個部分中的兩個gsub調用看起來像“黑魔法”,但一旦你知道它們的含義就很容易理解。 第一個發現的行開始由非數量最多的圖案(字符,隨后是(字符,然后替換什么也沒有。

第二個是類似的,但它刪除了最大的“ )序列,后跟任何字符到行尾”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM