Me gustaría imprimir todas las columnas que contengan palabras, por ejemplo, "sandía". A estaba pensando en usar juntas estas 2 fórmulas, porque funcionan por separado (una está haciendo algo para cada columna en el archivo y otra está verificando si la columna contiene una palabra específica).
awk '{for(i=1;i<=NF-1;i++) printf $i" "; print $i}' a.csv awk -F"," '{if ($2 == " watermelon") print $2}' a.csv
Pero cuando trato de ponerlos juntos, mi código no funciona.
#!/bin/bash awk '{for(i=1;i<=NF-1;i++) awk -F"," '{if ($i == " watermelon") print $i}' a.csv }' a.csv
Por ejemplo este es mi archivo a.csv
lp, type, name, number, letter 1, fruit, watermelon, 6, a 2, fruit, apple, 7, b 3, vegetable, onion, 8, c 4, vegetable, broccoli, 6, b 5, fruit, orange, 5, c
Y este es el resultado que me gustaría obtener, al buscar la palabra sandía
name watermelon apple onion broccoli orange
$ cat tst.awk BEGIN { FS=OFS=", " } NR==FNR { for (inFldNr=1; inFldNr<=NF; inFldNr++) { if ( $inFldNr == tgt ) { hits[inFldNr] } } next } FNR==1 { for (inFldNr=1; inFldNr<=NF; inFldNr++) { if ( inFldNr in hits ) { out2in[++numOutFlds] = inFldNr } } } { for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) { inFldNr = out2in[outFldNr] printf "%s%s", $inFldNr, (outFldNr<numOutFlds ? OFS : ORS) } }
$ awk -v tgt='watermelon' -f tst.awk file file name watermelon apple onion broccoli orange
La principal diferencia entre el enfoque anterior y el de @JamesBrown es que en la segunda pasada del archivo, mi secuencia de comandos solo recorre los campos que se generarán, mientras que James recorre todos los campos de entrada y, por lo tanto, será más lento en lo que presumiblemente es el caso normal donde no todos los campos de entrada tienen que ser de salida.
Con respecto a printf $i
en su código, por cierto, nunca haga eso, siempre haga printf "%s", $i
para cualquier dato de entrada, ya que el primero fallará cuando su entrada contenga caracteres de formato printf como %s
.
Aquí hay uno que procesa los datos dos veces:
$ awk -F', ' ' # remember to se OFS if you need one NR==FNR { # on the first run for(i=1;i<=NF;i++) # find if($i=="watermelon") # watermelon fields a[i] # and mark them next } FNR==1 { # in case there were no such field for(i in a) # test next # and continue exit # or exit } { # on the second run for(i=1;i<=NF;i++) if(i in a)b=b (b==""?"":OFS) $i # buffer those fields for output print b # and output b="" # clean that buffer for next record }' file file
Producción:
name watermelon apple onion broccoli orange