AWK: imprime el rango de columnas

si tengo un archivo csv en el siguiente formato:

column1,column2,column3,column4,column5,column6,column7,column8 

y quiero que awk solo imprima las columnas 2 a 7, usaría:

awk -F"," "{print $2 "," $3 "," $4 "," $5 "," $6 "," $7}" file.csv 

y get:

column2,column3,column4,column5,column6,column7 

¿hay alguna forma de concatenar las columnas 2-7 para simplificar el comando? Mientras estoy pensando en un archivo con un poco más de columnas, mi comando awk se volvería horriblemente largo.

Comentarios

  • ¿siempre querrá un conjunto consecutivo de columnas (por ejemplo, 2-7, o 5-15 o lo que sea)? Si es así, puede usar un bucle para imprimir las columnas. Si no, hay ' s no evite enumerar las columnas individuales que desea (aunque puede mezclar algunos bucles donde sea necesario). Además, ¿cuántas columnas?
  • Por último, es posible que desee para considerar un lenguaje como perl o python con un buen analizador CSV … especialmente si tiene los nombres de las columnas en la primera línea (varios de los módulos de análisis CSV de perl ' pueden usar estos para construir un hash con los nombres de columna como claves. i ' estoy bastante seguro de que los analizadores CSV de python ' pueden hacer algo similar). perl también tiene una excelente matriz & operadores de empalme de hash.
  • @cas sí, las columnas serían siempre s consecutivos.
  • ¿Responde esto a su pregunta? Imprimir rango de columnas separadas por comas y el resto sin separación por comas

Respuesta

$ awk -v b=2 -v e=7 "BEGIN{FS=OFS=","} {for (i=b;i<=e;i++) printf "%s%s", $i, (i<e ? OFS : ORS)}" file column2,column3,column4,column5,column6,column7 

b = número de campo inicial, e = número de campo final. Si necesita manejar archivos CSV con campos entre comillas, comas incrustadas, líneas nuevas, etc., consulte https://stackoverflow.com/q/45420535/1745001 .

Respuesta

El corte de la utilidad tiene una notación compacta:

cut -d, -f2-7 <input-file> 

produciendo:

columna2, columna3, columna4, columna5, columna6, columna7

Respondiendo al comentario de @PlasmaBinturong: mi intención era abordar el problema de una secuencia de llamada corta: " … mi comando awk se volvería horriblemente largo … ". Sin embargo, también se pueden encontrar códigos que organizan los campos como se desee. Por mucho que me guste awk, perl, python, a menudo me ha resultado útil crear una utilidad específica para ampliar las capacidades del estándar * nix. Así que aquí hay un extracto de un script de prueba, s2, que muestra las utilidades recortar y organizar, ambas permiten la reorganización y la duplicación, y la disposición también permite rangos de campo decrecientes:

FILE=${1-data1} # Utility functions: print-as-echo, print-line-with-visual-space. pe() { for _i;do printf "%s" "$_i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } pl " Input data file $FILE:" head $FILE pl " Results, cut:" cut -d, -f2-7 $FILE pl " Results, recut (modified as my-recut):" my-recut -d "," 7,6,2-5 < $FILE pl " Results, arrange:" arrange -s "," -f 5,3-1,7,5,3-4,5 $FILE 

produciendo resultados a partir de estas versiones:

OS, ker|rel, machine: Linux, 3.16.0-10-amd64, x86_64 Distribution : Debian 8.11 (jessie) bash GNU bash 4.3.30 cut (GNU coreutils) 8.23 recut - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) arrange (local) 1.15 ----- Input data file data1: column1,column2,column3,column4,column5,column6,column7,column8 ----- Results, cut: column2,column3,column4,column5,column6,column7 ----- Results, recut (modified as my-recut): column7,column6,column2,column3,column4,column5 ----- Results, arrange: column5,column3,column2,column1,column7,column5,column3,column4,column5 

my-recut es una pequeña modificación del código textutils recut, y arreglar es nuestra versión de un corte extendido . Más información:

recut Process fields like cut, allow repetitions and re-ordering. (what) Path : ~/bin/recut Version : - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) Length : 56 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Home : http://www1.cuni.cz/~obo/textutils/ (doc) Modules : (for perl codes) Getopt::Long 2.42 arrange Arrange fields, like cut, but in user-specified order. (what) Path : ~/bin/arrange Version : 1.15 Length : 355 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Modules : (for perl codes) warnings 1.23 strict 1.08 Carp 1.3301 Getopt::Euclid 0.4.5 

Mis mejores deseos … saludos, drl

Comentarios

  • A diferencia de Awk, genera las columnas en el orden del archivo de entrada, no en el orden del comando.
  • @PlasmaBinturong – vea la respuesta editada … saludos

Respuesta

sed -e " s/,/\n/7 ;# tag the end of col7 s/^/,/ ;# add a comma s/,/\n/2 ;# tag beginning of col2 s/.*\n\(.*\)\n.*/\1/ ;# perform surgery " file.csv 

Resultados:

column2,column3,column4,column5,column6,column7 

Respuesta

Probado con el siguiente comando y funcionó bien

awk -F "," "OFS=","{$1="";$NF="";print $0}" o| sed "s/^,//g"|sed "s/,$//g" 

salida

column2,column3,column4,column5,column6,column7 

Comentarios

  • gracias por la respuesta, funciona bien sin " o " antes de la primera sed pipe 🙂 se podían concatenar los dos sed en uno: sed "s/^,//g; s/,$//g"
  • ¿Por qué está probando el resultado de ejecutar

para decidir si imprimir la línea o no? También hay otros problemas (por ejemplo, NO necesita tuberías para comandos sed cuando ' está usando awk!) Pero esa parte de prueba OFS no tiene ningún sentido …

  • @EdMorton I ' aún espero una única awk solución …
  • @nath por qué ? ¿Qué ' está mal con la cut solución que @drl publicó ?
  • @EdMorton no, tienes razón, funciona bien. Pensé que no podría ser demasiado complicado con awk y tenía curiosidad más bien por el tema de interés que por una razón técnica 🙂
  • Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *