Linux
自定義數據格式和模式匹配
我正在嘗試使用模式匹配來格式化自定義數據。我沒有得到預期的格式。雖然我不精通 shell 腳本,但我能夠基於來自 SE 的多個來源的引用建構腳本。
需要一些建議的幫助,請指教。
輸入數據:
WWWW PPPA TTTT XX XY XA XB XB XC XY XE HHHH PPPA 400 XXX6 WWWW PPPB TTTT XB XC XY XE HHHH PPPB 200 XXX1 WWWW PPPC TTTT XX XY XA XB XB XC HHHH PPPC 300 XXX9 WWWW PPPA TTTT XA XB XB XC XN XX HHHH PPPA 300 XXX6 WWWW PPPD TTTT XX XY XA XB XB XC XY XE XN XA HHHH PPPD 500 XXX4
預期輸出:
WWWW PPPB TTTT XX XC XY XE HHHH PPPB 200 XXX1 WWWW PPPC TTTT XX XY XA XB XB XC HHHH PPPC 300 XXX9 WWWW PPPA TTTT XA XB XB XC XN XX XX XY XA XB XB XC XY XE HHHH PPPA 700 XXX6 WWWW PPPD TTTT XX XY XA XB XB XC XY XE XN XA HHHH PPPD 500 XXX4
請在此處查看評論,這也是通過引用其他程式碼建構的。我自己試圖理解這裡的邏輯。我是 shell 的基礎,正在尋找更多的學習和理解。
pattern='PPPA' awk -v ptn="${pattern}" ' # pass pattern in as awk variable "ptn" $0 ~ "^WWWW "ptn"$" { save=1 ; next } # start of group => set save flag; skip to next line $0 ~ "^HHHH "ptn" " { save=0 ; next } # end of group => clear save flag; skip to next line save { ++i ; line[i]=$0 ; next } # if save=1 then store current line in next position of array line[]; skip to next line { print } # otherwise print all other lines to stdout END { if ( i >= 1 ) # if we found any matches ... { printf "%-561s%s", "WWWW", ptn # print the new "WWWW" line for ( j=1 ; j<=i ; j++ ) # then loop through our list of indices ... { print line[j] } # printing the associated line[] element fmt="HHHH %s %02i\n" printf "%-69s%-491s%02i" "HHHH", i, ptn # print the "HHHH" line } } ' TESTX1.txt
我在這裡想要實現的是將 2 個數據集與匹配模式結合起來。先搜尋模式,如果匹配
WWWW
則搜尋模式。PPPA
然後俱樂部這個特定數據塊的開始和結束記錄。在輸入數據集中,您會看到 2 組具有
WWWW
和PPPA
模式。我想將它們組合為一個數據組,同時調整結束記錄數據計數:HHHH PPPA 400 XXX6 + HHHH PPPA 300 XXX6 = HHHH PPPA 700 XXX6 (400 + 300 = 700)
WWWW PPPA TTTT
將保持相同,因為它們對於兩個數據組是相同的。腳本輸出不符合預期:
WWWW PPPA TTTT XX XY XA XB XB XC XY XE WWWW PPPB TTTT XB XC XY XE HHHH PPPB 200 XXX1 WWWW PPPC TTTT XX XY XA XB XB XC HHHH PPPC 300 XXX9 WWWW PPPA TTTT XA XB XB XC XN XX WWWW PPPD TTTT XX XY XA XB XB XC XY XE XN XA HHHH PPPD 500 XXX4
感謝您的解決方案,發布數據未對其進行操作的實際數據。邏輯保持不變,但格式不同。
實際數據輸入
WWW PPPA TTTT XXXAAXX XX XY XA XB XB XC XY XE HHH 500 PPPA TTTT WWW PPPB TTTT XXXAAXX XB XC XY XE HHH 3500 PPPB TTTT WWW PPPA TTTT XXXAAXX XA XB XB XC XN XX HHH 1000 PPPA TTTT WWW PPPC TTTT XXXAABB XX XY XA XB XB XC XY XE XN XA HHH 4000 PPPC TTTT
實際數據預期輸出#
WWW PPPB TTTT XXXAAXX XB XC XY XE HHH 3500 PPPB TTTT WWW PPPA TTTT XXXAAXX XX XY XA XB XB XC XY XE XA XB XB XC XN XX HHH 1500 PPPA TTTT WWW PPPC TTTT XXXAABB XX XY XA XB XB XC XY XE XN XA HHH 4000 PPPC TTTT
您正在嘗試匹配
$
開始模式中的行尾,但輸入中的此位置沒有。頁眉/頁腳的END
塊格式也被破壞。稍作修改的程式碼:
pattern='PPPA' awk -v ptn="$pattern" ' $0 ~ "^WWWW " ptn " "{ save=1; header=$0; next } save && $0 ~ "^HHHH " ptn " "{ save=0; footer=$0; sum+=$3; next } save{ line[i++]=$0; next } 1 # print current record END{ if (i){ print header for (j=0;j<i;j++) print line[j] $0=footer # assign footer to current record $3=sum # replace 3rd field with sum print # print footer } } ' file
輸出:
WWWW PPPB TTTT XB XC XY XE HHHH PPPB 200 XXX1 WWWW PPPC TTTT XX XY XA XB XB XC HHHH PPPC 300 XXX9 WWWW PPPD TTTT XX XY XA XB XB XC XY XE XN XA HHHH PPPD 500 XXX4 WWWW PPPA TTTT XA XB XB XC XY XE XA XB XB XC XN XX HHHH PPPA 700 XXX6
實際數據的修改程式碼具有以下更改:
- 匹配
WWW
並HHH
作為第一個欄位,模式作為第二個(頁眉)或第三個(頁腳)欄位- 將舊的頁腳值保存在 中,用於在塊
oldvalue
中替換此值sum``END
- 使用第二個欄位作為頁腳值 (
sum
,oldvalue
)pattern='PPPA' awk -v ptn="$pattern" ' $1=="WWW" && $2==ptn{ save=1; header=$0; next } save && $1=="HHH" && $3==ptn{ save=0; oldvalue=$2; sum+=$2; footer=$0; next } save{ line[i++]=$0; next } 1 END{ if (i){ print header for (j=0;j<i;j++) print line[j] sub(oldvalue, sum, footer) # replace oldvalue with sum print footer } } ' file
輸出:
WWW PPPB TTTT XXXAAXX XB XC XY XE HHH 3500 PPPB TTTT WWW PPPC TTTT XXXAABB XX XY XA XB XB XC XY XE XN XA HHH 4000 PPPC TTTT WWW PPPA TTTT XXXAAXX XX XY XA XB XB XC XY XE XA XB XB XC XN XX HHH 1500 PPPA TTTT