빈 열에 문자열 삽입

빈 열에 문자열 삽입

빈 열에 텍스트를 삽입하려고 합니다. 파일이 탭으로 구분되어 있으며 빈 열에 텍스트를 삽입하려고 합니다. 예를 들어

Column1  Column2  Column3
string1  decs1    1234
         desc1    1255
string3           3443
string4  desc1    1
string5           435

비어 있는 열 1 또는 2에 NULL이라는 텍스트만 삽입하려고 합니다. 그래서 이렇게 보입니다. (2열이 비어 있는 경우 1열과 3열 사이에 이중 탭이 있습니다.)

column1  column2  column3
string1  decs1    1234
null     desc1    1255
string3  null     3443
string4  desc1    1
string5  null     435

사용해 보았지만 awk테스트에서는 모든 열 2에 NULL 텍스트를 삽입하지만 빈 항목이 있으면 세 번째 열을 열 2로 자릅니다.

awk '{sub("$", "NULL", $2)}; 1' file.txt > file2.txt

결과는 이렇습니다

column1  column2 column3
string1  desc1NULL 1234
string2  desc1NULL 1255
string3  3443NULL
string4  descNULL  1
string4  435NULL

분명히 잘못된 구문을 사용하고 있지만 수정하는 방법을 모르겠습니다.

감사해요

답변1

나는 이것을하는 것이 좋습니다 sed:

sed -E -e :1 -e 's/(^|\t)(\t|$)/\1null\2/;t1' yourfile

(이식성을 위해 실제 TAB 문자를 대신 사용하십시오 \t. 그러나 브라우저 복사/붙여넣기 이후에는 유지되지 않을 수 있습니다.)

빈 필드를 감지하는 방법은 무엇입니까? 어느 하나

  • ^\t줄 시작 부분의 탭 문자( ) 또는
  • \t\t두 탭( ) 사이에 아무 것도 없습니다 . 또는
  • \t$줄 끝에 탭 문자( ) 가 있습니다.

이 모든 경우에 s두 일치 항목 사이의 패턴을 바꾸십시오.

두 개의 빈 필드가 차례로 있는 경우 루프를 수행해야 하므로 무언가가 교체되면 t1마커로 점프합니다.:1

답변2

awk -F'\t' -v OFS='\t' '$1==""{ $1="NUll" }  $2==""{ $2="NUll" }1' infile

그리고sub("$", "NULL", $2)$, 2번 열의 문자열 끝을 $2"NULL" 문자열로 바꾸기 위해 sub() 함수를 호출하고 있습니다. 또한 이러한 열은 비어 있는 경우에만 "NULL"로 대체됩니다. sub()를 사용하면 다음을 수행할 수 있습니다.

awk -F'\t' -v OFS='\t' '
  $1==""{ sub(/.*/, "NULL", $1) }
  $2==""{ sub(/.*/, "NULL", $2) }
  $3=="" { "......" }
  # etc ...
1' infile

아니면:

awk -F'\t' -v OFS='\t' '
  { sub(/.*/, ($1==""?"NULL":$1), $1) }
  { sub(/.*/, ($2==""?"NULL":$2), $2) }
  # continue ...
1' infile

...하지만 이것은 이전의 첫 번째 명령보다 조금 더 나쁩니다. 또는 교체 작업이 단지 두 개의 열로 제한되지 않고 다음과 같은 경우에도 다음 변형을 사용할 수 있습니다.질소목록.

awk -F'\t' -v OFS='\t' -v N=2 '{
  while(colNr++<N){
      $colNr=($colNr==""?"NULL":$colNr)
  }
  colNr=0
}1' infile

답변3

모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.

$ awk 'BEGIN{FS=OFS="\t"} {for (i=1; i<=NF; i++) if ($i=="") $i="null"} 1' file
Column1 Column2 Column3
string1 decs1   1234
null    desc1   1255
string3 null    3443
string4 desc1   1
string5 null    435

s를 사용하면 sub()다음과 같습니다:

$ awk '{ while(sub(/\t\t/,"\tnull\t")); sub(/^\t/,"null\t"); sub(/\t$/,"\tnull")}1' file
Column1 Column2 Column3
string1 decs1   1234
null    desc1   1255
string3 null    3443
string4 desc1   1
string5 null    435

답변4

csvkit 도구를 사용하여 존재하지 않는 모든 값을 strings 로 대체하여 수정한 중간 JSON 문서를 만든 NULL다음 수정된 JSON 문서를 탭으로 구분된 CSV로 다시 변환합니다.

csvjson -t file |
jq '.[] |= map_values(. // "NULL")' |
in2csv --blanks -f json | csvformat -T

여기서는 csvjson -t먼저 이라는 파일에서 탭으로 구분된 입력을 구문 분석 하여 fileJSON을 출력합니다 . 그런 다음 jq생성된 문서를 수정하기 위해 호출하여 모든 null 값을 문자열로 바꿉니다 NULL. 이 호출은 JSON 문서를 읽고 문자열을 null 값으로 바꾸는 것을 방지하기 in2csv위해 CSV를 생성합니다 . 마지막으로 Reformat CSV data to be tab-delimited를 사용합니다 .--blanksNULLcsvformat -T


마찬가지지만 jq전체 데이터 세트의 배열을 읽지 않고도 개별 행의 스트림을 처리할 수 있습니다. 그런 다음 데이터는 in2csv.

csvjson --stream -t file |
jq -c 'map_values(. // "NULL")' |
in2csv -f ndjson --blanks | csvformat -T

관련 정보