Unix : 연속 쉼표를 찾아 연속 파이프 라인으로 대체
Jan 08 2021
큰 따옴표 CSV를 Unix에서 파이프 라인으로 구분 된 txt 파일로 변환하고 있습니다. 다음 sed 명령을 사용하여 ","를 | 그런 다음 시작 및 끝 큰 따옴표를 제거하십시오.
sed -e 's/","/|/g' -e 's/"//g' filenm.csv > filenm.txt
그러나 파일에 큰 따옴표없이 연속 된 쉼표가있는 것처럼 보이며 대체되지 않습니다.
Col1|col2|col3|col4|col5|col6|col7|col8
Val1|val2|val3,,,,val7|val8
이제 이러한 모든 연속 쉼표를 비어 있거나 null 필드를 나타내는 연속 파이프 라인으로 변환하려고합니다.
또한 다른 필드에는 변경해서는 안되는 필드 값 안에 쉼표가 있습니다.
나는 그것을 위해 아래를 사용해 보았지만 작동하지 않습니다.
sed -e 's/,{1,\}/|{1,\}/g' filenm.csv > filenm.txt
메모장에서 열린 샘플 csv 파일 :
"ID","Name","DOB","Age","Address","City","State","Country","Phone number"
"123","ABC","12/20/2020","15","No.38,3rd st, RRR NNN, TRT",,,,"9999999999"
"456","DEF","12/20/2020",,,,,"test-country","9999999999"
"465","XYZ",,,"No.38,3rd st, RRR NNN, TRT",,,,"9999999999"
문제를 재현하고 해결하는 데 도움이 되었기를 바랍니다.
미리 감사드립니다 ....
답변
2 WiktorStribiżew Jan 08 2021 at 22:37
다음을 사용할 수 있습니다 perl
.
perl -pe 's/"([^"]*)"|,/defined($1) ? $1 : "|"/ge' filenm.csv > filenm.txt
세부 사항 :
"([^"]*)"|,
-일치하는 정규식 패턴"
, 그런 다음"
a 이외의 0 개 이상의 문자를 그룹 1로 캡처 한 다음 a와 일치"
하거나,
다른 모든 컨텍스트에서 a와 일치 합니다.defined($1) ? $1 : "|"
- 우 (그룹 1이 일치하는 경우) 그룹 1의 값과 일치하거나 대체 교체, 또는으로|
합니다 (이 경우,
일치 된)ge
- (모든 발생을 대체 함)을g
나타내며 Perl이 RHS를 Perl 표현식으로 취급하게합니다.global
e
참조 온라인 테스트를 :
#!/bin/bash
s='"ID","Name","DOB","Age","Address","City","State","Country","Phone number"
"123","ABC","12/20/2020","0","No.38,3rd st, RRR NNN, TRT",,,,"9999999999"'
perl -pe 's/"([^"]*)"|,/defined($1) ? $1 : "|"/ge' <<< "$s"
산출:
ID|Name|DOB|Age|Address|City|State|Country|Phone number
123|ABC|12/20/2020|0|No.38,3rd st, RRR NNN, TRT||||9999999999
4 potong Jan 08 2021 at 23:05
이것은 당신을 위해 일할 수 있습니다 (GNU sed) :
sed -E ':a;s/^(("[^",]*",+)*"[^",]*),/\1\n/;ta;y/,\n/|,/' file
,
의 사이에있는 "
's를 개행 문자로 반복적으로 바꾼 다음 ,
's는 |
's, 개행 문자는 ,
's 로 번역하십시오 .
1 RamanSailopal Jan 09 2021 at 00:35
awk 사용 :
awk -F \" '{ for(i=1;i<=NF;i++) { if ($i ~ /^[,]{2,}$/) { $i="," } } OFS="\"";gsub("\",\"","\"|\"",$0)}1' sample.csv
설명:
awk -F \" '{ # Set the field delimiter to double quote
for(i=1;i<=NF;i++) {
if ($i ~ /^[,]{2,}$/) {
$i="," # Loop through each field and if is contains 2 or more commas, set that field to one comma } } OFS="\""; gsub("\",\"","\"|\"",$0) # Substitute "," for "|"
}1' sample.csv
1 Daweo Jan 09 2021 at 01:50
나는 AWK
다음과 같은 방식으로 GNU 를 사용할 것입니다. 하자 file.txt
만족을
"ID","Name","DOB","Age","Address","City","State","Country","Phone number"
"123","ABC","12/20/2020","15","No.38,3rd st, RRR NNN, TRT",,,,"9999999999"
"456","DEF","12/20/2020",,,,,"test-country","9999999999"
"465","XYZ",,,"No.38,3rd st, RRR NNN, TRT",,,,"9999999999"
그때
awk 'BEGIN{FS="\"";OFS=""}{for(i=1;i<=NF;i+=2){$i=gensub(/,/,"|","g",$i)};print $0}' file.txt
산출
ID|Name|DOB|Age|Address|City|State|Country|Phone number
123|ABC|12/20/2020|15|No.38,3rd st, RRR NNN, TRT||||9999999999
456|DEF|12/20/2020|||||test-country|9999999999
465|XYZ|||No.38,3rd st, RRR NNN, TRT||||9999999999
나는 첫 번째와 마지막 열이 결코 비어 있지 않다고 가정했습니다. I 사용 "
(이들은 단독으로 함유 필드로 분리 한 후 각 홀수 필드에서 ,
I 모든 변경) ,
로 |
. 마지막으로 변경된 선 전체를 인쇄합니다.
(GNU Awk 5.0.1에서 테스트 됨)