Unisci più comandi sed in uno script per l'elaborazione del file CSV


34

Avere un file CSV come questo:

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

e alla ricerca di risultati come:

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

in altre parole, rimuovendo "FOOTER", virgolette all'inizio, alla fine e intorno |.

Finora questo codice funziona:

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

Come vedi il problema è che crea 4 file extra.

Ecco un'altra soluzione, che ha l'obiettivo di non creare file extra e di fare la stessa cosa in un singolo script. Non funziona molto bene

#!/bin/ksh

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

1
Dal momento che hai delle virgolette puoi avere delle nuove righe nei campi. il vostro sednon è andare a lavorare con questo, solo con il csv semplificata. Utilizzare un linguaggio di programmazione con una libreria in grado di gestire file CSV reali (Python / Perl / Ruby).
Anthon,

Risposte:


44

Prima di tutto, come ha mostrato Michael, puoi semplicemente combinare tutti questi in un unico comando:

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

Penso che alcune sedimplementazioni non possano farcela e potrebbero aver bisogno di:

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

Detto questo, sembra che i tuoi campi siano definiti da |e vuoi solo rimuovere "tutto il campo, lasciando quelli che si trovano all'interno del campo. In tal caso, potresti fare:

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

Oppure, con GNU sed:

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

Puoi anche usare 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

Questo funzionerebbe anche:

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

Esempio:

$ 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"

bella versione

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

1
Questo non riguarda il piè di pagina.
Terdon

3
Ma ciò rimuoverà l'ultima riga, indipendentemente dal suo contenuto. In caso FOOTERcontrario, rimuoverà i dati desiderati.
terdon
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.