단락의 다차원 데이터 구문 분석

단락의 다차원 데이터 구문 분석

PDF 보고서의 데이터를 구문 분석하고 특정 흥미로운 요소를 필터링하려고 합니다. 이것을 사용하여 pdftotext -layout시작점으로 다음 형식의 데이터를 얻습니다.

Record   Info           Interesting  
123      apple          yep         
         orange         nope         
         lemon          yep          
----------------------------------------------- 
456      dragonfruit    yep
         cucumber       nope         
-----------------------------------------------
789      kumquat        nope         
         lychee         yep          
         passionfruit   yep          
         yam            nope         
-----------------------------------------------
987      grapefruit     nope         

내 예상 출력은 다음과 같습니다. 각 " Interesting" 과일과 해당 레코드 번호입니다.와는 별개로과일이 기록상 첫 번째인 경우:

Record   Info
123      lemon
789      lychee
789      passionfruit

현재 영감을 받아이 문제, ------레코드 구분 기호를 로 대체 \n\n하고 를 사용하여 레코드 헤더를 제거했습니다 sed. 그러면 일치하는 기록이 있는 단락을 찾을 수 있습니다 awk.

awk -v RS='' '/\n   .....................yep/'

{3}.{21}(그 중 하나 awk또는 이와 유사한 것으로 글을 쓰는 방법을 알아내는 것은 확실히 또 다른 하루의 싸움입니다 :/)

그러면 다음과 같은 깔끔한 단락이 생성됩니다.

123      apple          yep         
         orange         nope         
         lemon          yep          

789      kumquat        nope         
         lychee         yep          
         passionfruit   yep          
         yam            nope         

여기에서 다음을 통해 원하는 출력을 얻을 수 있습니다.

  • 첫 번째 레코드 번호 열 또는 이전 행의 두 번째 레코드 번호 열에서 채워진 두 번째 레코드 번호 열을 추가합니다.
  • 첫 번째 열에 레코드 번호가 있는 행 삭제
  • 관심 없는 행 삭제
  • cut마지막 열 중

나는 일반적으로 여기서 올바른 방향으로 가고 있습니까, 아니면 다차원 데이터를 구문 분석하는 더 직접적인 방법이 있습니까? 아마도 grep흥미로운 줄( yep레코드 번호가 있든 없든) 을 핑한 다음 grep거기에서 비어 있지 않은 레코드 번호가 있는 다음 줄로 거꾸로 작업하면 될까요?

답변1

상황이 너무 복잡해질 수 있습니다.

$ cat input
Record   Info           Interesting
123      apple          yep
         orange         nope
         lemon          yep
-----------------------------------------------
456      dragonfruit    yep
         cucumber       nope
-----------------------------------------------
789      kumquat        nope
         lychee         yep
         passionfruit   yep
         yam            nope
-----------------------------------------------
987      grapefruit     nope
$ awk 'BEGIN {OFS="\t"; print "Record","Info"} NF==3 && NR!=1 { number=$1 } NF!=3 && $2 ~ /yep/ {print number,$1}' input
Record  Info
123     lemon
789     lychee
789     passionfruit

awk스크립트를 좀 더 수직적으로 만들려면 작동 방식을 설명하세요.

BEGIN {                    # This block executes before any data
   OFS="\t";               # are parsed, and simply prints a header.
   print "Record","Info"
}
NF==3 && NR!=1 {           # This block will run on any row (line)
   number=$1               # with three fields other than the first
}
NF!=3 && $2 ~ /yep/ {      # On rows with three fields where the second
   print number,$1         # matches the regex /yup/, print the number
}                          # grabbed before, and the fruit.

관련 정보