2012-05-30 13 views
11

A volte viene visualizzato un file CSV con un ritorno a capo all'interno di una cella. Questo non è un formato accettabile per un programma che lo utilizzerà come input.Conteggio di virgole in una riga in bash

Per rilevare se una riga di input è suddivisa, ho determinato che una riga non valida non avrebbe il numero previsto di virgole in essa. Esiste un bash o un altro strumento di riga di comando comune di Unix che mi consente di contare le virgole nella riga? Se necessario, posso scrivere un programma Python o Perl per farlo, ma se possibile, vorrei aggiungere una riga o due a uno script bash esistente per causare un errore se il conteggio delle virgole è sbagliato. Qualche idea?

+1

Perché non è possibile cercare i ritorni a capo e eliminarli? –

+1

Suppongo che il destinatario significhi interruzioni di riga in generale e che "la loro eliminazione" non funzionerà, poiché le righe valide finiscono anche in un carattere di avanzamento riga. – lanzz

+8

'a, b," c, d, e "' ha 3 campi ma 4 virgole – Stefan

risposta

29

Striscia di tutto, ma le virgole, e poi contare il numero di caratteri a sinistra:

$ echo foo,bar,baz | tr -cd , | wc -c 
2 
5

per contare il numero di volte in cui compare una virgola, si può usare qualcosa come awk:

string=(line of input from CSV file) 
echo "$string" | awk -F "," '{print NF-1}' 

Ma questo in realtà non è sufficiente per determinare se un campo ha ritorni a capo in esso. I campi possono contenere virgole purché contornate da virgolette.

-2

sufficiente rimuovere tutti i ritorni a capo:

tr -d "\r" old_file > new_file 
+1

Perché il downvote? –

+0

downvote perché il ritorno a capo è valido se delimita i record all'interno del file, quindi non possono essere semplicemente rimossi. –

2

Prova Perl:

$ perl -ne 'print [email protected]{[/,/g]},"\n"' 
a 
0 
a,a 
1 
a,a,a,a,a 
4 
+1

Puoi costringerlo a uno scalare più facilmente aggiungendo la nuova riga: 'stampa @ {[/,/g]}. "\ n" ' –

+1

L'uso di perl è ... una scelta interessante. Se dovessi usare perl, penso che andrei con: 'perl -F, -anE 'dire $ # F''. Ma questa è una soluzione originale ... quindi +1! –

+0

@WilliamPursell +2 per essere un Wizard Perl ;-) – ceving

4

In puro Bash:

while IFS=, read -ra array 
do 
    echo "$((${#array[@]} - 1))" 
done < inputfile 

o

while read -r line 
do 
    count=${line//[^,]} 
    echo "${#count}" 
done < inputfile 
0

A seconda di cosa si sta tentando di fare con i dati CSV, può essere utile usare uno script di wrapper come csvquote per sostituire temporaneamente le newline problematiche (e le virgole) all'interno dei campi citati, quindi ripristinarli. Per esempio:

csvquote inputfile.csv | wc -l 

e

csvquote inputfile.csv | cut -d, -f1 | csvquote -u 

può essere il genere di cosa che stai cercando. Vedere [https://github.com/dbro/csvquote][1] per il codice e ulteriori informazioni

Problemi correlati