awk sin imprimir nueva línea

169

Quiero que la variable suma / NR se imprima de lado a lado en cada iteración. ¿Cómo evitamos que awk imprima nueva línea en cada iteración? En mi código, se imprime una nueva línea por defecto en cada iteración

for file in cg_c ep_c is_c tau xhpl
printf "\n $file" >> to-plot.xls
    for f in 2.54 1.60 800 
        awk '{sum+=$3}; END  {print  sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
    done
done

Quiero que la salida aparezca así

cg_c ans1  ans2  ans3  
ep_c ans1  ans2  ans3 
is_c ans1  ans2  ans3
tau  ans1  ans2  ans3 
xhpl ans1  ans2  ans3

mi salida actual es así

**cg_c**
ans1
ans2
ans3
**ep_c**
ans1
ans2
ans3
**is_c**
ans1
ans2
ans3
**tau**
ans1
ans2
ans3
**xhpl**
ans1
ans2
ans3
Sharat Chandra
fuente

Respuestas:

220

awk '{sum+=$3}; END {printf "%f",sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls

printinsertará una nueva línea por defecto. No desea que eso suceda, por lo tanto, úselo printf.

CodeRain
fuente
44
Pero cuenta que printfinterpreta %sasí que usa en printf "%s" whateverlugar de printf whatever.
Matthieu
1
printf "%s",whateverOlvidaste la coma. También puede ampliar con más variables y separarlas con una coma.
Hielke Walinga
74

La variable ORS (separador de registro de salida) en AWK tiene como valor predeterminado "\ n" y se imprime después de cada línea. Puede cambiarlo a "" en la BEGINsección si desea que todo se imprima consecutivamente.

danben
fuente
66
Es posible que incluso desee configurarlo ""(sin espacio) para que no tenga separación en absoluto.
mschilli
8
Así:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
Fredrik Erlandsson
2
O ORS="\r"si desea, por ejemplo, imprimir un contador que muestre la progresión.
Skippy le Grand Gourou
47

Supongo que muchas personas están entrando en esta pregunta buscando una manera de evitar la nueva línea awk. Por lo tanto, voy a ofrecer una solución para eso, ¡ya que la respuesta al contexto específico ya estaba resuelta!

En awk, printinserta automáticamente un ORSdespués de la impresión. ORSsignifica "separador de registro de salida" y por defecto es la nueva línea. Así que cada vez que diga print "hi"awk imprime "hola" + nueva línea.

Esto se puede cambiar de dos maneras diferentes: usando un vacío ORSo usando printf.

Usando un vacío ORS

awk -v ORS= '1' <<< "hello
man"

Esto devuelve "helloman", todos juntos.

El problema aquí es que no todos los awks aceptan configurar un vacío ORS, por lo que probablemente tenga que configurar otro separador de registros.

awk -v ORS="-" '{print ...}' file

Por ejemplo:

awk -v ORS="-" '1' <<< "hello
man"

Devuelve "hello-man-".

Usando printf(preferible)

Mientras se printadjunta ORSdespués del registro, printfno lo hace. Por lo tanto, printf "hello"solo imprime "hola", nada más.

$ awk 'BEGIN{print "hello"; print "bye"}'
hello
bye
$ awk 'BEGIN{printf "hello"; printf "bye"}'
hellobye

Finalmente, tenga en cuenta que, en general, esto pierde una nueva línea final, por lo que el indicador de shell estará en la misma línea que la última línea de la salida. Para limpiar esto, utilícelo END {print ""}para que se imprima una nueva línea después de todo el procesamiento.

$ seq 5 | awk '{printf "%s", $0}'
12345$
#    ^ prompt here

$ seq 5 | awk '{printf "%s", $0} END {print ""}'
12345
fedorqui 'así que deja de dañar'
fuente
5

de una sola mano

awk '/^\*\*/{gsub("*","");printf "\n"$0" ";next}{printf $0" "}' to-plot.xls
ghostdog74
fuente
1
Nota de menor importancia: no utilice nunca printf $0, ya que $0puede contener cadenas como %F, etc ... Siguiendo fácilmente falla (al menos con gawk 3.1.5): echo "%F"|awk '{printf $0}'. Use el printf "%s",$0en su lugar.
Vlad
2

Simplemente puede usar ORS dinámicamente de esta manera:

awk '{ORS="" ; print($1" "$2" "$3" "$4" "$5" "); ORS="\n"; print($6-=2*$6)}' file_in > file_out

Andrea Barletta
fuente
1

Si Perl es una opción, aquí hay una solución usando el ejemplo de fedorqui:

seq 5 | perl -ne 'chomp; print "$_ "; END{print "\n"}'

Explicación:
chompelimina la nueva línea
print "$_ "imprime cada línea, agregando un espacio que
el END{}bloque se usa para imprimir una nueva línea

salida: 1 2 3 4 5

Chris Koknat
fuente