awk senza stampare newline


169

Voglio che la somma variabile / NR sia stampata fianco a fianco in ogni iterazione. Come possiamo evitare che awk stampi newline in ogni iterazione? Nel mio codice una linea nuova viene stampata di default in ogni iterazione

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

Voglio che l'output appaia così

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

la mia attuale produzione è così

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

Risposte:


220

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

printinserirà una nuova riga per impostazione predefinita. Non vuoi che ciò accada, quindi usa printfinvece.


4
Ma attenzione che printfinterpreta %scosì usa printf "%s" whateverinvece di printf whatever.
Matthieu,

1
printf "%s",whateverHai dimenticato la virgola. È inoltre possibile estendere con più variabili e separarle con una virgola.
Hielke Walinga,

74

La variabile ORS (separatore record di output) in AWK viene impostata automaticamente su "\ n" e viene stampata dopo ogni riga. Puoi cambiarlo in "" nella BEGINsezione se vuoi che tutto sia stampato consecutivamente.


6
Si potrebbe anche voler impostare ""(senza spazio) per non avere alcuna separazione.
mschilli,

8
In questo modo:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
Fredrik Erlandsson,

2
O ORS="\r"se si desidera ad esempio stampare un contatore che mostra la progressione.
Skippy le Grand Gourou

47

Immagino che molte persone stiano entrando in questa domanda alla ricerca di un modo per evitare la nuova linea awk. Quindi, offrirò una soluzione proprio a questo, poiché la risposta al contesto specifico era già risolta!

In awk, printinserisce automaticamente un ORSdopo la stampa. ORSsta per "separatore record di output" e per impostazione predefinita è la nuova riga. Quindi ogni volta che dici print "hi"awk stampa "ciao" + nuova riga.

Questo può essere modificato in due modi diversi: usando un vuoto ORSo usando printf.

Usando un vuoto ORS

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

Questo restituisce "Helloman", tutti insieme.

Il problema qui è che non tutti i awk accettano di impostare un valore vuoto ORS, quindi probabilmente devi impostare un altro separatore di record.

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

Per esempio:

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

Restituisce "ciao-uomo-".

Utilizzo printf(preferibile)

Mentre si printallega ORSdopo il record, printfnon lo fa. Quindi, printf "hello"stampa solo "ciao", nient'altro.

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

Infine, nota che in generale questo manca una nuova riga finale, quindi il prompt della shell sarà nella stessa riga dell'ultima riga dell'output. Per pulire questo, utilizzare in END {print ""}modo che una nuova riga verrà stampata dopo tutta l'elaborazione.

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

$ seq 5 | awk '{printf "%s", $0} END {print ""}'
12345

5

senso unico

awk '/^\*\*/{gsub("*","");printf "\n"$0" ";next}{printf $0" "}' to-plot.xls

1
Nota minore: non utilizzare mai printf $0, dal momento che $0può contenere stringhe come %F, ecc ... In seguito facilmente fallisce (almeno con GAWK 3.1.5): echo "%F"|awk '{printf $0}'. Usa printf "%s",$0invece.
Vlad,

2

Puoi semplicemente utilizzare ORS in modo dinamico in questo modo:

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


1

Se Perl è un'opzione, ecco una soluzione usando l'esempio di fedorqui:

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

Spiegazione:
chomprimuove la nuova riga
print "$_ "stampa ogni riga, aggiungendo uno spazio
il END{}blocco viene utilizzato per stampare una nuova riga

produzione: 1 2 3 4 5

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.