separador print examples comparar columnas campos archivos unix csv awk

print - awk unix



Extrae columnas específicas del archivo delimitado usando Awk (8)

Lo siento si esto es demasiado básico. Tengo un archivo csv donde las columnas tienen una fila de encabezado (v1, v2, etc.). Entiendo que para extraer las columnas 1 y 2, tengo que hacer lo siguiente: awk -F "," ''{print $1 "," $2}'' infile.csv > outfile.csv . Pero, ¿qué pasa si tengo que extraer, por ejemplo, las columnas 1 a 10, 20 a 25 y 30, 33? Como una adición, ¿hay alguna manera de extraer directamente con los nombres de encabezado en lugar de con los números de columna?


Como mencionó @Tom, los enfoques de corte y awk en realidad no funcionan para CSV con cadenas entre comillas. Una alternativa es un módulo para python que proporciona la herramienta de línea de comandos csvfilter. Funciona como corte, pero maneja correctamente las columnas de CSV:

csvfilter -f 1,3,5 in.csv > out.csv

Si tiene python (y debería), puede instalarlo simplemente así:

pip install csvfilter

Tenga en cuenta que la indexación de columna en csvfilter comienza con 0 (a diferencia de awk, que comienza con $ 1). Más información en https://github.com/codeinthehole/csvfilter/


No sé si es posible hacer rangos en awk. Podría hacer un ciclo for, pero tendría que agregar manejo para filtrar las columnas que no desea. Probablemente sea más fácil hacer esto:

awk -F, ''{OFS=",";print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$20,$21,$22,$23,$24,$25,$30,$33}'' infile.csv > outfile.csv

algo más que considerar, y esto más rápido y más conciso:

cut -d "," -f1-10,20-25,30-33 infile.csv > outfile.csv

En cuanto a la segunda parte de su pregunta, probablemente escribiría un script en Perl que sepa cómo manejar las filas del encabezado, analizar los nombres de las columnas de stdin o un archivo y luego hacer el filtrado. Probablemente sea una herramienta que me gustaría tener para otras cosas. No estoy seguro de hacerlo en un solo trazador de líneas, aunque estoy seguro de que se puede hacer.


No uso awk, pero la forma más sencilla en que pude hacer esto fue simplemente usar csvtool . También tuve otros casos de uso para usar csvtool y puede manejar las comillas o los delimitadores de manera apropiada si aparecen dentro de los datos de la columna en sí.

csvtool format ''%(2)/n'' input.csv csvtool format ''%(2),%(3),%(4)/n'' input.csv

Reemplazar 2 con el número de columna extraerá efectivamente los datos de columna que está buscando.


Otros han respondido a su pregunta anterior. Para esto:

Como una adición, ¿hay alguna manera de extraer directamente con los nombres de encabezado en lugar de con los números de columna?

No lo he probado, pero puedes guardar el índice de cada encabezado en un hash y luego usar ese hash para obtener su índice más adelante.

for(i=0;i<$NF;i++){ hash[$i] = i; }

Luego, úsala:

j = hash["header1"]; print $j;


Otros idiomas tienen atajos para rangos de números de campo, pero no awk, tendrás que escribir tu código como tu miedo ;-)

awk -F, ''BEGIN {OFS=","} { print $1, $2, $3, $4 ..... $30, $33}'' infile.csv > outfile.csv

No existe una función directa en awk para usar nombres de campo como especificadores de columna.

Espero que esto ayude.


Puede usar un for-loop para abordar un campo con $ i :

ls -l | awk ''{for(i=3 ; i<8 ; i++) {printf("%s/t", $i)} print ""}''


Si Perl es una opción:

perl -F, -lane ''print join ",",@F[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32]''

-a línea de autosplits en la @F campos @F . Los índices comienzan en 0 (no 1 como en awk)
-F, separador de campo es,

Si su archivo CSV contiene comas entre comillas, los analizadores de CSV completos como Perl''s Text::CSV_XS están diseñados para manejar ese tipo de rareza.

perl -MText::CSV_XS -lne ''BEGIN{$csv=Text::CSV_XS->new()} if($csv->parse($_)){@f=$csv->fields();print (join ",",@f[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32])}''

Proporcioné más explicación dentro de mi respuesta aquí: análisis de archivo csv usando gawk


Tabulator es un conjunto de herramientas de línea de comandos de Unix para trabajar con archivos csv que tienen líneas de encabezado. Aquí hay un ejemplo para extraer columnas por nombre de un archivo test.csv:

name,sex,house_nr,height,shoe_size arthur,m,42,181,11.5 berta,f,101,163,8.5 chris,m,1333,175,10 don,m,77,185,12.5 elisa,f,204,166,7

Luego tblmap -k name,height test.csv produce

name,height arthur,181 berta,163 chris,175 don,185 elisa,166