2022년 2월 7일 월요일

따옴표 안에 필드 분리자가 있는 텍스트 파일을 awk로 파싱하려면?

콤마로 구분된 필드로 구성된 텍스트 파일을 awk로 파싱하여 특정 컬럼만을 추출하고자 한다. 각 컬럼은 드는 다음과 같이 큰따옴표로 구분된 상태라고 가정하자. 

"column_1","column_2","column_3",...

그런데 하필이면 어떤 컬럼은 영문 이름 정보를 담고 있어서 그 안에 콤마가 또 들어가 있는 상태이다.

"Jeong, Haeyoung","other_column",...

단순히 'awk -F,' 명령을 이용해서는 이러한 상황을 잘 처리하지 못한다. 마이크로소프트 엑셀에서는 어떻게 대응하는지 아직 확인해 보지 않았다. 따옴표가 둘러싼 내부에서는 필드 구분자(field delimiter)와 동일한 문자를 만나더라도 건드리지 않게 하는 지혜가 필요하다. 이는 널리 논의된 문제이고 이미 해결 방안도 잘 알려져 있다. Starck Overflow 웹사이트에서도 중복된 질문과 답으로 표시되어 있기 때문이다.

    How to make awk ignore the field delimiter inside double quotes? [duplicate]

    예를 들어서 1번과 4번 컬럼만을 추출하려면 이렇게 하면 된다. 내가 처음에 참고하여 사용했던 방법이다.

    $ awk '{while(match($0,/("[^"]+",|[^,]*,|([^,]+$))/,a)){
         $0=substr($0,RSTART+RLENGTH);b[++x]=a[0]}
         print b[1] b[4];x=0}' sequences.csv > accession.csv.mod
    

    그런데 이 코드는 이해하기 난해하다. 답변 중에서 가장 상단에 있는 것이 가장 깔끔하고 보기에도 좋다. GNU awk의 '-vFPAT' 옵션을 쓰면 된다고 한다. 다음과 같이 명령어를 구성하는 같은 결과를 얻는다.

    $ awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '{print $1,$4}' file
    

    콤마를 다른 문자로 바꾸면 다양한 형태의 텍스트 파일에 대응할 수 있다.

    댓글 없음: