SED를 사용하여 다른 단어에 속하지 않는 CSV 파일에서 전체 단어를 제거합니다.

SED를 사용하여 다른 단어에 속하지 않는 CSV 파일에서 전체 단어를 제거합니다.

나는 이 질문에 대한 답을 찾고 있었고, 가까워졌지만 충분히 가까워지지는 않았습니다. 아무것도 바꾸지 않고 "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).

다음으로 결과 요소를 반복하여 mapsubst요소에 메서드를 적용합니다. 여기서는 사이에 아무 것도 없이 /^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

https://raku.org

관련 정보