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 dossed
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 …
awk
solución … cut
solución que @drl publicó ? awk
y tenía curiosidad más bien por el tema de interés que por una razón técnica 🙂