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
Bor
sumber
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
terdon
sumber
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
'
Michael Durrant
sumber
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