awk 및 파이프 값을 사용하여 파이프로 구분된 파일에서 중복 항목을 제거하는 방법은 무엇입니까?

awk 및 파이프 값을 사용하여 파이프로 구분된 파일에서 중복 항목을 제거하는 방법은 무엇입니까?

이 방법을 사용하여 파이프로 구분된 파일에서 여러 열을 기반으로 중복 항목을 제거하려고 합니다.여러 동적 열을 기반으로 중복을 제거하는 방법 그런데 아래와 같이 큰따옴표 안의 값에 파이프가 있는 것을 발견했습니다.

3|XX|""|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7
3|XX|"2025035|6|15|0|0|15|39"|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7

마지막 열 위치 6과 위치 2를 확인하면 두 행이 중복되지만 위치 3의 파이프 때문에 작동하지 않습니다. 아래 코드에서 큰따옴표로 파이프를 이스케이프하려면 어떻게 해야 합니까?

$4='2,6'
awk -v c="$4"  -F'|' 'BEGIN{split(c,k,",")} {key=""; for (i in k) key=key FS $(k[i])} !seen[key]++'

티아

답변1

GNU awk를 사용하면 다음을 수행할 수 있습니다 FPAT.

$ awk -v c='2,6' -v FPAT='([^|]*)|("[^"]*")' 'BEGIN{split(c,k,",")} {key=""; for (i in k) key=key RS $(k[i])} !seen[key]++' file
3|XX|""|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7

이와 같이 큰따옴표를 중첩할 수 있는 경우 "foo""bar"FPAT 할당을 다음으로 변경하세요.FPAT='[^|]*|("([^"]|"")*")'

바라보다awk를 사용하여 csv를 효율적으로 구문 분석하는 가장 강력한 방법은 무엇입니까더 많은 정보를 알고 싶습니다.

답변2

awk와 같은 것을 사용하여 이 작업을 수행할 수 있습니다.밀러

mlr --csv --fs '|' --implicit-csv-header --headerless-csv-output --quote-original filter '
  key = $2.FS.$6; @seen[key] += 1; @seen[key] == 1'
' file
3|XX|""|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7

!@seen[$6]++( 밀러가 이미 알고 있기 때문에 정확한 비유를 사용하는 것은 불가능해 보입니다.부울로 자동 변환되지 않음또한 후증가 연산자도 아닙니다. )

관련 정보