Unix: Temukan dan ganti koma yang berurutan ke pipeline yang berurutan
Saya mengonversi CSV yang dikutip ganda menjadi file txt yang dibatasi pipa di Unix. Saya telah menggunakan perintah sed berikut untuk mengganti "," menjadi | lalu hapus tanda kutip ganda awal dan akhir.
sed -e 's/","/|/g' -e 's/"//g' filenm.csv > filenm.txt
Namun file tersebut tampaknya memiliki koma yang berurutan tanpa tanda kutip ganda dan tidak diganti.
Col1|col2|col3|col4|col5|col6|col7|col8
Val1|val2|val3,,,,val7|val8
Sekarang saya ingin mengubah semua koma yang berurutan ini menjadi pipeline yang berurutan karena menunjukkan bidang kosong atau nol.
Dan bidang lain juga memiliki koma di dalam nilai bidang yang tidak boleh diubah.
Saya mencoba menggunakan di bawah ini untuk itu, tetapi tidak berhasil.
sed -e 's/,{1,\}/|{1,\}/g' filenm.csv > filenm.txt
contoh file csv dibuka di notepad:
"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"
Saya harap ini membantu mereproduksi masalah dan menyelesaikannya.
Terima kasih sebelumnya....
Jawaban
Anda dapat menggunakan perl
:
perl -pe 's/"([^"]*)"|,/defined($1) ? $1 : "|"/ge' filenm.csv > filenm.txt
Detailnya :
"([^"]*)"|,
- pola regex yang cocok"
, lalu menangkap ke dalam Grup 1 karakter apa pun yang tidak ada atau lebih selain"
dan kemudian cocok dengan a"
, atau hanya cocok dengan a,
di semua konteks lainnyadefined($1) ? $1 : "|"
- Kanan, pengganti, yang menggantikan pertandingan baik dengan nilai Grup 1 (jika Grup 1 cocok) atau dengan|
(jika,
cocok)ge
-g
singkatanglobal
(menggantikan semua kejadian) dane
membuat Perl memperlakukan RHS sebagai ekspresi Perl.
Lihat tes online :
#!/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"
Keluaran:
ID|Name|DOB|Age|Address|City|State|Country|Phone number
123|ABC|12/20/2020|0|No.38,3rd st, RRR NNN, TRT||||9999999999
Ini mungkin berhasil untuk Anda (GNU sed):
sed -E ':a;s/^(("[^",]*",+)*"[^",]*),/\1\n/;ta;y/,\n/|,/' file
Ganti baris ,
antara "
dengan baris baru, lalu terjemahkan ,
untuk |
baris dan baris baru untuk ,
.
Menggunakan awk:
awk -F \" '{ for(i=1;i<=NF;i++) { if ($i ~ /^[,]{2,}$/) { $i="," } } OFS="\"";gsub("\",\"","\"|\"",$0)}1' sample.csv
Penjelasan:
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
Saya akan menggunakan GNU AWK
untuk cara berikut ini. Biarkan file.txt
konten menjadi
"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"
kemudian
awk 'BEGIN{FS="\"";OFS=""}{for(i=1;i<=NF;i+=2){$i=gensub(/,/,"|","g",$i)};print $0}' file.txt
keluaran
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
Saya berasumsi bahwa kolom pertama dan terakhir tidak pernah kosong. Saya gunakan "
sebagai pemisah bidang dan kemudian di setiap bidang ganjil (ini hanya berisi ,
) saya mengubah semua ,
menjadi |
. Akhirnya saya mencetak seluruh baris yang diubah tersebut.
(diuji di GNU Awk 5.0.1)