2011-12-25 17 views
48

Dado un archivo con los datos de este tipo (es decir, el archivo stores.dat)UNIX - recuento de columnas en el archivo

sid|storeNo|latitude|longitude 
2|1|-28.03720000|153.42921670 
9|2|-33.85090000|151.03274200 

¿Cuál sería un comando a la salida el número de nombres de columna?

decir, en el ejemplo anterior sería 4. (número de caracteres de tubería + 1 en la primera línea)

estaba pensando algo como:

awk '{ FS = "|" } ; { print NF}' stores.dat 

pero devuelve todas las líneas en lugar de solo el primero y para la primera línea devuelve 1 en lugar de 4

Respuesta

76
awk -F'|' '{print NF; exit}' stores.dat 

Simplemente salga justo después de la primera línea.

+1

o 'awk -F '|' 'NR == 1 {print NF}' stores.dat' –

+10

@JaypalSingh: que leerá el archivo completo; no es necesario, mejor detenerse antes. – Mat

+0

Ambos parecen devolver la misma salida correcta, ¿hay algún beneficio de rendimiento de 1 sobre el otro (o algún otro beneficio)? – toop

9

A menos que esté usando espacios allí, debería poder usar | wc -w en la primera línea.

wc es "Número de palabras", que simplemente cuenta las palabras en el archivo de entrada. Si envía solo una línea, le indicará la cantidad de columnas.

+0

He intentado: head -1 stores.dat | wc -w Pero eso no devuelve lo que estoy buscando – toop

+0

Eso es porque no estás reemplazando el '|' con un espacio - 'wc' contará palabras, que tienen que estar separadas por espacios. Use 'head -1 stores.dat | tr '|' '' | wc -w' –

+2

Agregue su comentario a la respuesta para completar. – Xofo

28

esto es una solución (para mí: yo no uso awk muy a menudo):

mostrar la primera fila del archivo que contiene los datos, sustituir todas las tuberías con saltos de línea y luego contar las líneas:

$ head -1 stores.dat | tr '|' '\n' | wc -l 
+6

Para archivos con muchas columnas (piense en datos de SNP) este es el camino a seguir. La solución de Mat devolvió "awk: límite de programa excedido: número máximo de campos de tamaño = 32767". –

1

Si ha instalado Python podría intentar:

python -c 'import sys;f=open(sys.argv[1]);print len(f.readline().split("|"))' \ 
    stores.dat 
+0

en este caso particular, es más corto de leer desde la entrada estándar 'cat x.txt | python -c "print raw_input(). count ('|') + 1" ' –

+0

¡más corto sí, pero no más rápido, si hay muchos archivos largos! Supuse que quería una solución más rápida en el ojo de los archivos de datos puros (significa seguramente grandes). –

1

Esto es por lo general lo que utilizo para contar el número de campos:

head -n 1 file.name | awk -F'|' '{print NF; exit}' 
4

usted podría intentar

gato ARCHIVO | awk '{print} NF'

1

solución Perl similar a la solución de awk de Mat:

perl -F'\|' -lane 'print $#F+1; exit' stores.dat 

He probado esto en un archivo con 1000000 columnas.


Si el separador de campo es de espacio en blanco (uno o más espacios o tabuladores) en lugar de un tubo:

perl -lane 'print $#F+1; exit' stores.dat 
0

Basado en la respuesta Cat Kerr. Este comando está trabajando en Solaris

awk '{print NF; exit}' stores.dat 
+0

Y luego está en la respuesta aceptada menos el separador de campo adecuado. Esto devolvería "1" para la entrada de ejemplo. –

+0

Esto es esencialmente lo mismo que la respuesta aceptada sin separador de campo, ya que Bejamin dice devuelve 1 pero debería funcionar para archivos delimitados por espacios. – discipulus

0

puede intentar:

head -1 stores.dat | grep -o \| | wc -l 
0

seleccionar cualquier fila en el archivo (en el ejemplo siguiente, que es la segunda fila) y contar el número de columnas, donde el delimitador es un espacio:

sed -n 2p text_file.dat | tr ' ' '\n' | wc -l 
Cuestiones relacionadas