Bergabung dengan beberapa perintah sed dalam satu skrip untuk memproses file CSV


34

Memiliki file CSV seperti ini:

HEADER
"first, column"|"second "some random quotes" column"|"third ol' column"
FOOTER

dan mencari hasil seperti:

HEADER
first, column|second "some random quotes" column|third ol' column

dengan kata lain menghapus "FOOTER", tanda kutip di awal, akhir dan sekitar |.

Sejauh ini kode ini berfungsi:

sed '/FOOTER/d' csv > csv1 | #remove FOOTER
sed 's/^\"//' csv1 > csv2 | #remove quote at the beginning
sed 's/\"$//' csv2 > csv3 | #remove quote at the end
sed 's/\"|\"/|/g' csv3 > csv4 #remove quotes around pipe

Seperti yang Anda lihat masalahnya adalah ia membuat 4 file tambahan.

Berikut adalah solusi lain, yang memiliki tujuan untuk tidak membuat file tambahan dan melakukan hal yang sama dalam satu skrip. Itu tidak bekerja dengan baik.

#!/bin/ksh

sed '/begin/, /end/ { 
        /FOOTER/d
        s/^\"//
        s/\"$//
        s/\"|\"/|/g 
}' csv > csv4

1
Karena Anda memiliki penawaran, Anda dapat memiliki baris baru di bidang tersebut. Anda sedtidak akan bekerja dengan itu, hanya dengan csv yang disederhanakan. Gunakan bahasa pemrograman dengan pustaka yang dapat menangani file CSV nyata (Python / Perl / Ruby).
Anthon

Jawaban:


44

Pertama-tama, seperti yang ditunjukkan Michael, Anda bisa menggabungkan semua ini menjadi satu perintah:

sed '/^FOOTER/d; s/^\"//; s/\"$//; s/\"|\"/|/g' csv > csv1

Saya pikir beberapa sedimplementasi tidak dapat mengatasinya dan mungkin perlu:

  sed -e '/^FOOTER/d' -e 's/^\"//' -e 's/\"$//' -e 's/\"|\"/|/g' csv > csv1

Yang mengatakan, sepertinya bidang Anda ditentukan oleh |dan Anda hanya ingin menghapus "seluruh bidang, meninggalkan yang ada di dalam bidang. Dalam hal ini, Anda dapat melakukan:

$ sed '/FOOTER/d; s/\(^\||\)"/\1/g; s/"\($\||\)/\1/g' csv 
HEADER
first, column|second "some random quotes" column|third ol' column

Atau, dengan GNU sed:

sed -r '/FOOTER/d; s/(^|\|)"/\1/g; s/"($|\|)/\1/g' csv 

Anda juga bisa menggunakan Perl:

$ perl -F"|" -lane 'next if /FOOTER/; s/^"|"$// for @F; print @F' csv 
HEADER
first, column|second some random quotes column|third ol' column

13

Ini juga akan berfungsi:

sed 's / ^ "//; s /" | "/ | / g; s /" "$ /" /'

Contoh:

$ echo '"this"|" and "ths""|" and "|" this 2"|" also "this", "thi", "and th""' | 
sed 's/^"//; s/"|"/|/g; s/""$/"/'
this| and "ths"| and | this 2| also "this", "thi", "and th"

versi cantik

sed '
s/^"//
s/"|"/|/g
s/""$/"/
$d
'

1
Ini tidak berurusan dengan catatan kaki.
terdon

3
Tapi itu akan menghapus baris terakhir apa pun isinya. Jika tidak ada FOOTER, itu akan menghapus data yang diinginkan.
terdon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.