패턴 일치를 사용하여 사용자 정의 데이터의 형식을 지정하려고 합니다. 예상되는 형식을 얻지 못했습니다. 쉘 스크립팅에 대해 잘 모르지만 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
여기 주석을 참조하세요. 이 역시 다른 코드를 참조하여 작성되었습니다. 나는 여기의 논리를 직접 이해하려고 노력하고 있습니다. 나는 쉘에 대한 매우 기본적인 지식을 가지고 있으며 더 많이 배우고 이해하고 싶습니다.
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
여기서 달성하려는 것은 두 개의 데이터 세트를 일치하는 패턴으로 결합하는 것입니다. 먼저 패턴을 검색한 후, 일치하면 다시 패턴을 검색하세요 WWWW
. PPPA
그런 다음 이 특정 데이터 블록의 시작 및 끝 레코드가 병합됩니다.
WWWW
입력 데이터 세트에는 및 패턴이 있는 2개의 그룹이 있음을 알 수 있습니다 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
답변1
시작 패턴의 줄 끝을 일치시키려고 $
하지만 입력의 해당 위치에 줄 끝이 없습니다. 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