그래서 수백만 행의 쉼표로 구분된 값이 포함된 큰 파일이 있습니다.
132.3,-23.3,1659614391.4174244,539.0,0,l_top
132.3,-23.1,1659614391.4174244,548.0,0,l_top
131.9,-22.900000000000002,1659614391.4174244,539.0,0,l_top
132.1,-22.700000000000003,1659614391.4174244,541.0,0,l_top
132.20000000000002,-22.5,1659614391.4174244,548.0,0,l_top
131.8,-22.200000000000003,1659614391.4174244,543.0,0,l_top
133.5,-22.3,1659614391.4174244,551.0,0,l_top
133.0,-22.1,1659614391.4174244,547.0,0,l_top
133.5,-21.900000000000002,1659614391.4174244,545.0,0,l_top
133.5,-21.700000000000003,1659614391.4174244,558.0,0,l_top
…
l_top
awk를 사용하여 아래와 같이 마지막 열 값이 있는 행을 추출하려고 합니다.
awk -F ',' '{ if ($6 == "l_top") { print } else { exit }}' <file>
아무것도 인쇄되지 않습니다. 예를 들어 다른 열을 필터링하면 $5 == 0
제대로 작동합니다. 어쩌면 줄 끝 부분에 문제가 있는 것일까요? 열 값을 기준으로 필터링하는 올바른 방법은 무엇입니까?
답변1
이는 "프로그램 종료"를 의미하기 때문에 프로그램 exit
이 첫 번째 줄에서 시작되지 않을 것입니다 l_top
.next
awk -F ',' '{ if ($6 == "l_top") { print } else { next }}' <file>
그러나 무언가가 true인 경우 awk의 기본 작업은 해당 행을 인쇄하는 것이므로 명시적으로 지정할 필요조차 없습니다 print
.
awk -F, '$6 == "l_top"' file
그렇지 않으면:
grep ',l_top$' file
답변2
테든의 답변문제에 대한 해결책이며 필터 기준을 충족하지 않는 첫 번째 레코드에서 코드가 종료되는 이유도 설명합니다(즉, exit
실행을 종료합니다). 그러나 CSV 파일에 더 복잡한 필드(쉼표, 줄 바꿈 등)가 포함된 경우 CSV 인식 도구를 사용하여 원하는 레코드를 추출해야 합니다.
여기서 사용되는 것은밀러( mlr
)는 헤드리스 CSV 파일을 구문 분석 file.csv
하고 마지막 필드가 문자열인 레코드를 추출합니다 l_top
.
mlr --csv -N filter '$[NF] == "l_top"' file.csv
또는 숫자로 여섯 번째 열에 액세스하려면
mlr --csv -N filter '$6 == "l_top"' file.csv
또는 헤더가 있고 마지막 필드의 헤더가 다음과 같은 경우 label
(여기에서는 제거되지 않음 -N
):
mlr --csv filter '$label == "l_top"' file.csv
답변3
DOS 줄 끝이 있으므로 $6
대신 다음을 참조하세요 l_top
.l_top\r
https://stackoverflow.com/questions/45772525/why-does-my-tool-output-overwrite-itself-and-how-do-i-fix-it.
명령을 다음으로 변경합니다.
awk -F ',' '{ sub(/\r$/,""); if ($6 == "l_top") { print } else { exit }}' <file>