필드에 부동 소수점 값이 있는 CSV 파일의 레코드를 필터링하고 postal_code
헤더도 출력에 포함시키고 싶습니다.
샘플 CSV 파일은 다음과 같습니다.
> ca test.csv
employee_id|postal_code
1|56024.4
1|752066
예상되는 출력은 다음과 같습니다.
employee_id|postal_code
1|752066
내가 시도한 것:
> awk '$2 != "." {print $0} ' test.csv
1|56024.4
1|752066
답변1
명령 은 awk
공백으로 구분된 두 번째 필드가 점인지 테스트합니다. 두 번째 공백으로 구분된 필드가 없으므로 파일의 모든 내용을 출력합니다.
사용밀러mlr
( ) 는 점이 포함된 필드(예: 헤더 포함)의 출력에서 레코드를 필터링합니다 .postal_code
ca
$ mlr --csv --fs pipe filter -S '$postal_code !=~ "[.]"' file
employee_id|postal_code
1|752066
필드 값을 정규식 ( 으로 대체 가능 )과 일치시켜 필드 $postal_code !=~ "[.]"
값을 테스트하고 테스트에 성공하면 레코드를 삭제하는 필터 표현식 입니다.postal_code
[.]
\.
이 작업 -S
에 대한 옵션은 filter
필드에 대한 유형 추론을 끄므로 데이터는 여전히 부동 소수점이 아닌 문자열입니다.
필터 표현식을 사용하여 필드에 숫자만 포함된 레코드를 $postal_code =~ "^[[:digit:]]+$"
허용할 수도 있습니다. postal_code
특정 자릿수(예: )를 요구하여 이를 더욱 엄격하게 만들 수 있습니다 $postal_code =~ "^[[:digit:]]{6}$"
.
답변2
사용sed
$ sed -E '/[^|]*\|[0-9]+\./s/.*//' input_file
employee_id|postal_code
1|752066
답변3
또는 다음과 같이 사용하십시오 grep
.
$ grep -P '.*\|[0-9]{5,9}$' test.csv
1|752066
편집하다:OP의 편집된 질문을 바탕으로
$ sed -n -E '1p;2,${/^.+\|[0-9]{5,9}$/p}' test.csv
employee_id|postal_code
1|752066
일반 라이너로도 비슷한 작업을 수행할 수 있으며 awk
일반 라이너를 사용할 가능성은 사라졌습니다.grep
편집하다:타이밍 정보 추가
$ time -p ( for i in {1..1000}; do
<command>
done )
위의 <명령>을 다음으로 바꾸세요.
sed -n -E '1p;2,${/^.+\|[0-9]{5,9}$/p}' test.csv > /dev/null
리얼 3.10
유저 2.19
시스템 0.95awk -F'|' 'NR==1;$2 !~ /[[:punct:]]/' test.csv > /dev/null
리얼 3.23
유저 2.19
시스템 1.06mlr --csv --fs pipe filter -S '$postal_code !=~ "[.]"' test.csv > /dev/null
리얼 16.91
유저 5.08
시스템 12.37
답변4
이와 같이:
$ awk -F'|' 'NR==1;$2 !~ /[[:punct:]]/' file
employee_id|postal_code
1|752066