awk ohne Newline drucken

169

Ich möchte, dass die Variable sum / NR in jeder Iteration nebeneinander gedruckt wird. Wie vermeiden wir, dass awk in jeder Iteration Zeilenumbrüche druckt? In meinem Code wird standardmäßig in jeder Iteration eine neue Zeile gedruckt

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

Ich möchte, dass die Ausgabe so aussieht

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

Mein aktueller Output ist so

**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
quelle

Antworten:

219

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

printfügt standardmäßig eine neue Zeile ein. Sie möchten nicht, dass dies geschieht, verwenden Sie es printfstattdessen.

CodeRain
quelle
4
Aber denken Sie daran, dass printfInterpretationen %sso verwenden printf "%s" whateverstatt printf whatever.
Matthieu
1
printf "%s",whateverDu hast das Komma vergessen. Sie können auch um weitere Variablen erweitern und diese durch ein Komma trennen.
Hielke Walinga
74

Die Variable ORS (Output Record Separator) in AWK ist standardmäßig "\ n" und wird nach jeder Zeile gedruckt. Sie können es im BEGINAbschnitt in "" ändern, wenn Sie möchten, dass alles nacheinander gedruckt wird.

danben
quelle
6
Vielleicht möchten Sie es sogar so einstellen ""(kein Leerzeichen), dass es überhaupt keine Trennung gibt.
Mschilli
8
So:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
Fredrik Erlandsson
2
Oder ORS="\r"wenn Sie zB einen Zähler drucken möchten, der den Fortschritt anzeigt.
Skippy le Grand Gourou
47

Ich denke, viele Leute gehen in diese Frage ein und suchen nach einer Möglichkeit, die neue Zeile zu vermeiden awk. Daher werde ich genau dafür eine Lösung anbieten, da die Antwort auf den spezifischen Kontext bereits gelöst wurde!

In awk, printfügt automatisch eine ORSnach dem Drucken. ORSsteht für "Ausgabedatensatztrennzeichen" und verwendet standardmäßig die neue Zeile. Wenn Sie also sagen, dass print "hi"awk "hi" + neue Zeile druckt.

Dies kann auf zwei verschiedene Arten geändert werden: mit einem leeren ORSoder mit printf.

Mit einem leeren ORS

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

Dies gibt insgesamt "helloman" zurück.

Das Problem hierbei ist, dass nicht alle awks das Setzen eines Leerzeichens akzeptieren ORS, sodass Sie wahrscheinlich ein anderes Datensatztrennzeichen setzen müssen.

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

Beispielsweise:

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

Gibt "Hallo-Mann-" zurück.

Verwenden printf(vorzuziehen)

Während printAttaches ORSnach der Aufzeichnung printfnicht. Also printf "hello"druckt nur "Hallo", sonst nichts.

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

Beachten Sie schließlich, dass im Allgemeinen eine letzte neue Zeile fehlt, sodass sich die Shell-Eingabeaufforderung in derselben Zeile wie die letzte Zeile der Ausgabe befindet. Verwenden Sie zum Reinigen END {print ""}eine neue Zeile, die nach der gesamten Verarbeitung gedruckt wird.

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

$ seq 5 | awk '{printf "%s", $0} END {print ""}'
12345
fedorqui 'SO hör auf zu schaden'
quelle
5

Einweg

awk '/^\*\*/{gsub("*","");printf "\n"$0" ";next}{printf $0" "}' to-plot.xls
Ghostdog74
quelle
1
Kleiner Hinweis: niemals verwenden printf $0, da dies $0Zeichenfolgen wie %Fusw. enthalten kann. Folgendes kann leicht fehlschlagen (zumindest mit GAWK 3.1.5) : echo "%F"|awk '{printf $0}'. Verwenden Sie printf "%s",$0stattdessen die.
Vlad
2

Sie können ORS einfach so dynamisch verwenden:

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

Andrea Barletta
quelle
1

Wenn Perl eine Option ist, finden Sie hier eine Lösung am Beispiel von fedorqui:

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

Erläuterung:
chompEntfernt die neue
print "$_ "Zeile, die jede Zeile druckt, und fügt ein Leerzeichen hinzu, mit dem
der END{}Block eine neue Zeile druckt

Ausgabe: 1 2 3 4 5

Chris Koknat
quelle