빈 열에 텍스트를 삽입하려고 합니다. 파일이 탭으로 구분되어 있으며 빈 열에 텍스트를 삽입하려고 합니다. 예를 들어
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
먼저 이라는 파일에서 탭으로 구분된 입력을 구문 분석 하여 file
JSON을 출력합니다 . 그런 다음 jq
생성된 문서를 수정하기 위해 호출하여 모든 null 값을 문자열로 바꿉니다 NULL
. 이 호출은 JSON 문서를 읽고 문자열을 null 값으로 바꾸는 것을 방지하기 in2csv
위해 CSV를 생성합니다 . 마지막으로 Reformat CSV data to be tab-delimited를 사용합니다 .--blanks
NULL
csvformat -T
마찬가지지만 jq
전체 데이터 세트의 배열을 읽지 않고도 개별 행의 스트림을 처리할 수 있습니다. 그런 다음 데이터는 in2csv
.
csvjson --stream -t file |
jq -c 'map_values(. // "NULL")' |
in2csv -f ndjson --blanks | csvformat -T