나는 이 질문에 대한 답을 찾고 있었고, 가까워졌지만 충분히 가까워지지는 않았습니다. 아무것도 바꾸지 않고 "NULL" 텍스트가 포함된 CSV 파일을 받습니다. 예:
- 입력하다
12345,George,MCNULLMAN,NULL,green,NULL
- 교체 결과는 다음과 같습니다.
12345,George,MCNULLMAN,,green,
나는 이것을 테스트로 시도했지만 단어 경계에서는 쉼표를 고려하지 않는 것 같습니다.
echo "MCNULLMAN,HELLO,NULL,NULL" | sed 's|bNULL/b||g'
중간에 사람이 포함된 이름을 sed 's|NULL||g'
받기 전까지는 한동안 잘 작동했습니다 . NULL
어떤 제안이 있으십니까?
답변1
표 형식 데이터로 작업할 때 다음을 사용하는 것이 좋습니다 awk
.
awk 'BEGIN{FS=OFS=","}{for (i=1;i<=NF;i++) if ($i=="NULL") $i=""}1' input.csv
그러면 입력 및 출력 필드 구분 기호가 로 설정됩니다 ,
. 그런 다음 행의 모든 필드를 반복 NULL
하고 정확히 동일하면 빈 문자열로 바꿉니다. 모든 수정 사항이 포함된 행을 인쇄하도록 지시합니다(있는 경우) 1
.awk
필요한 경우 sed
필드 구분 기호를 하드코딩하는 것이 좋습니다(줄 시작으로 선행 쉼표를 허용하고 줄 끝으로 후행 쉼표를 허용).
sed -E 's/(^|,)(NULL)(,|$)/\1\3/g' input.csv
이는 캡처 그룹을 활용하여 이전 및 다음 필드 구분 기호(수정 중인 필드에 따라 쉼표 또는 줄의 시작/끝일 수 있음)의 실제 값을 기록하고 전체 "이전 -구분 기호+필드+후행-"을 대체합니다. 구분 기호" "선행 구분 기호+후행 구분 기호"로만 결합됩니다.
참고하세요이는 인용되지 않는 "간단한 CSV" 파일에만 적용됩니다 NULL
.
답변2
사용밀러( mlr
)는 NULL
헤더 없는 CSV 입력 파일의 정확한 문자열에 대한 모든 필드를 지웁니다.
$ cat file.csv
12345,George,MCNULLMAN,NULL,green,NULL
$ mlr --csv -N put 'for (k,v in $*) { v == "NULL" { $[k] = "" } }' file.csv
12345,George,MCNULLMAN,,green,
이는 복잡한 참조가 포함된 CSV 파일에도 적용됩니다.
$ cat file.csv
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL","NULL",green,"""NULL"""
$ mlr --csv -N put 'for (k,v in $*) { v == "NULL" { $[k] = "" } }' file.csv
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL",,green,"""NULL"""
위의 예제 레코드에는 문자열만 포함하는 필드가 하나 있는데 NULL
, 네 번째 필드(앞 green
)입니다. 또한 불필요한 따옴표 세트도 포함되어 있습니다. (마지막 필드는 "NULL"
리터럴 따옴표를 포함하는 이므로 지워지지 않습니다. NULL
두 번째 줄의 첫 번째 필드는 리터럴 줄 바꿈을 포함하는 첫 번째 필드의 일부입니다. 마찬가지로 NULL,NULL
값이 있는 필드는 터치되지 않습니다.)
답변3
사용 awk
:
awk '{sub(/^NULL,/, ",");
gsub(/,NULL,/, ",,");
sub(/,NULL$/, ",")}1' file
사용 csvsql
:
file.csv를 간단한 CSV 파일로 사용합니다.
12345,George,MCNULLMAN,NULL,green,NULL
$ csvsql -H -I --query 'select * from file' file.csv | csvformat -K 1
12345,George,MCNULLMAN,,green,
복잡한 참조가 포함된 file.csv입니다.
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL","NULL",green,"""NULL"""
$ csvsql -H -I --query 'select * from file' file.csv | csvformat -K 1
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL",,green,"""NULL"""
-H
을 위한--no-header-row
.-I
을 위한--no-inference
. 이 옵션이 없으면 명령이12345
로 변경됩니다12345.0
.-K n
을 위한--skip-lines
. 먼저 건너뛰기N철사.
csvsql -H
이 명령 은 헤더 행을 추가하기 때문에 사용됩니다 . - K 1
삭제하세요.
답변4
사용행복하다(이전 Perl_6)
~$ raku -ne '.split(",").map(*.subst: :global, /^NULL$/ ).join(",").put;' file
또는
~$ raku -ne '.split(",")>>.subst( :global, /^NULL$/ ).join(",").put;' file
위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 자동 인쇄가 아닌 한 줄씩 플래그를 사용하여 파일을 한 줄씩 읽습니다 -ne
. 이러한 플래그는 Raku에게 각 플래그 줄 다음에 코드를 실행하도록 지시합니다.
입력 데이터(예: 행)는 Raku의 $_
테마 변수에 로드됩니다. 여기에서 텍스트는 $_.split
쉼표로 시작됩니다(위 참고: 선행을 제거 $_
하고 그냥 쓸 수 있음 .split
).
다음으로 결과 요소를 반복하여 map
각 subst
요소에 메서드를 적용합니다. 여기서는 사이에 아무 것도 없이 /^NULL$/
시작하고 끝나는 요소와 일치하는 모든 항목이 아무 것도 없는 것으로 대체됩니다( 부사/인수는 중복되지만 다른 경우에는 유용할 수 있음).NULL
:global
마지막으로 수정된 요소는 join
쉼표 및 out 을 사용하여 그룹화됩니다 put
.
입력 예:
12345,George,MCNULLMAN,NULL,green,NULL
12345,George,MCNULLMAN,NULL,green,nail
NULL,George,MCNULLMAN,NULL,green,neal
예제 출력:
12345,George,MCNULLMAN,,green,
12345,George,MCNULLMAN,,green,nail
,George,MCNULLMAN,,green,neal