2012-05-30 27 views
11

A veces recibo un archivo CSV que tiene un retorno de carro dentro de una celda. Este no es un formato aceptable para un programa que lo usará como entrada.Contando comas en una línea en bash

Para detectar si una línea de entrada está dividida, determiné que una línea incorrecta no tendría el número esperado de comas en ella. ¿Existe una herramienta de bash u otra herramienta común de línea de comandos de Unix que me permita contar las comas en la línea? Si es necesario, puedo escribir un programa de Python o Perl para hacerlo, pero si es posible, me gustaría agregar una línea o dos a un script bash existente para que falle si el recuento de las comas es incorrecto. ¿Algunas ideas?

+1

¿Por qué no puede simplemente buscar retornos de carro y eliminarlos? –

+1

Supongo que asker significa saltos de línea en general, y "simplemente eliminarlos" no funcionará, ya que las líneas válidas también terminan en un carácter de avance de línea. – lanzz

+8

'a, b," c, d, e "' tiene 3 campos pero 4 comas – Stefan

Respuesta

29

Gaza todo menos las comas, y luego contar el número de caracteres restantes:

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

para contar el número de veces que aparece una coma, puede usar algo como awk:

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

Pero esto realmente no es suficiente para determinar si un campo tiene retorno de carro en él. Los campos pueden tener comas dentro siempre que estén rodeados por comillas.

-2

Basta con retirar todos los retornos de carro:

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

¿Por qué el voto a favor? –

+0

downvote porque el retorno de carro es válido si delimita los registros dentro del archivo, por lo que no pueden simplemente eliminarse. –

2

Trate Perl:

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

Puede forzarlo a un escalar más fácilmente al agregar la nueva línea: 'print @ {[/,/g]}. "\ n" ' –

+1

Usar Perl es ... una opción interesante. Si fuera a usar Perl, creo que iría con: 'perl -F, -anE 'say $ # F''. Pero esta es una solución novedosa ... ¡así que +1! –

+0

@WilliamPursell +2 por ser un Perl Wizard ;-) – ceving

4

En pura 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

Dependiendo de lo que intente hacer con los datos CSV, puede ser útil usar una secuencia de comandos contenedora como csvquote para reemplazar temporalmente las líneas nuevas problemáticas (y las comas) dentro de los campos entrecomillados, y luego restaurarlos. Por ejemplo:

csvquote inputfile.csv | wc -l 

y

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

puede ser el tipo de cosa que usted está buscando. Consulte [https://github.com/dbro/csvquote][1] para obtener el código y más información