2010-04-21 5 views
5

Kommentarzeilen werden im NR gezählt.AWK: Gibt es eine Flagge, um Kommentare zu ignorieren?

  1. Gibt es eine Flagge, um Kommentare zu ignorieren?
  2. Wie können Sie den Bereich in AWK begrenzen, nicht wie Rohrleitung | sed -e '1d', um Kommentarzeilen zu ignorieren?

Beispiel

$ awk '{sum+=$3} END {avg=sum/NR} END {print avg}' coriolis_data 
0.885491       // WRONG divided by 11, should be by 10 
$ cat coriolis_data 
#d-err-t-err-d2-err 
.105 0.005 0.9766 0.0001 0.595 0.005 
.095 0.005 0.9963 0.0001 0.595 0.005 
.115 0.005 0.9687 0.0001 0.595 0.005 
.105 0.005 0.9693 0.0001 0.595 0.005 
.095 0.005 0.9798 0.0001 0.595 0.005 
.105 0.005 0.9798 0.0001 0.595 0.005 
.095 0.005 0.9711 0.0001 0.595 0.005 
.110 0.005 0.9640 0.0001 0.595 0.005 
.105 0.005 0.9704 0.0001 0.595 0.005 
.090 0.005 0.9644 0.0001 0.595 0.005 

Antwort

6

Gerade Dekrement NR sich auf Kommentarzeilen:

awk '/^[[:space:]]*#/ { NR-- } {sum+=$3} END { ... }' coriolis_data 

Okay, das die Frage, die Sie gefragt, antwortete, aber die Frage, die Sie wirklich gemeint:

awk '{ if ($0 ~ /^[[:space:]]*#/) {NR--} else {sum+=$3} END { ... }' coriolis_data 

(Es ist mehr awk-ish zu verwenden Muster außerhalb der Blöcke wie in der ersten Antwort, aber um es so zu tun, müssten Sie Ihr Kommentarmuster zweimal schreiben.)

Edit: Will schlägt in den Kommentaren /.../ {NR--; next} vor, um den if-else Block zu vermeiden. Mein Gedanke ist, dass dies sauberer aussieht, wenn Sie komplexere Aktionen für die übereinstimmenden Datensätze haben, aber das ist nicht so wichtig für so etwas Einfaches. Nimm deinen Liebling!

+0

Nicht sicher genug, da $ 3 in einer Kommentarzeile hinzugefügt werden könnte. –

+0

Ein Problem dort ist, dass Sie $ 3 auf die Summe sogar in Kommentarzeilen hinzufügen, nicht wahr? – nsayer

+0

@Bruno Jinx! :) – nsayer

0

Ich würde sie mit sed entfernen Sie zuerst, dann Leerzeilen mit grep entfernen.

sed 's/#.*//' < coriolis_data | egrep -v '^$' | awk ...

+0

Mein Punkt war zu vermeiden, sed Dinge wie verwenden: sed -e 's @^#. * $ @@ g' -e/^ $/d coriolis_data | awk ... – hhh

+0

Ich glaube nicht, dass awk automatische Entfernung von Kommentaren hat. Zum einen gibt es mehrere Syntaxen zum Angeben von Kommentaren. Awk ist zu verallgemeinert ein Werkzeug, um integrierte Unterstützung für einen bestimmten zu haben. – nsayer

2

Die Datei, die Sie für AWK bereitstellen, um zu analysieren, ist keine Quelldatei, es ist Daten, daher weiß AWK nichts über seine Konfiguration. Mit anderen Worten, für AWK sind mit # beginnende Zeilen nichts besonderes.

Das heißt, natürlich können Sie Kommentare überspringen, aber Sie müssen eine Logik dafür erstellen: Sagen Sie AWK, alles zu ignorieren, was nach einem "#" kommt und zählen Sie die Anzahl der Zeilen.

awk 'BEGIN {lines=0} {if(substr($1, 0, 1) != "#") {sum+=$3; lines++} } END {avg=sum/lines} END {print avg}' coriolis_data 

Sie können natürlich zur besseren Lesbarkeit einrücken.

+0

Ich denke, es durch sed erstens ist lesbarer, fwiw. – nsayer

+0

Wenn Sie Kommentare in der Mitte einer Zeile beginnen können, müssen Sie diesem Einstrich Code hinzufügen. Schrei einfach hier und ich werde es für dich bereitstellen. –

+0

Besser, eine Regex zu verwenden, um nach Kommentarzeilen zu suchen, und Sie können NR selbst ändern, anstatt Ihren eigenen Zeilenzähler zu behalten. – Cascabel

0

Es gibt einen einfacheren Weg, es zu tun!

$ awk '!/#/ {print $0}' coriolis_data 
.105 0.005 0.9766 0.0001 0.595 0.005 
.095 0.005 0.9963 0.0001 0.595 0.005 
.115 0.005 0.9687 0.0001 0.595 0.005 
.105 0.005 0.9693 0.0001 0.595 0.005 
.095 0.005 0.9798 0.0001 0.595 0.005 
.105 0.005 0.9798 0.0001 0.595 0.005 
.095 0.005 0.9711 0.0001 0.595 0.005 
.110 0.005 0.9640 0.0001 0.595 0.005 
.105 0.005 0.9704 0.0001 0.595 0.005 
.090 0.005 0.9644 0.0001 0.595 0.005 

Korrektur: nein, ist es nicht!

$ awk '!/#/ {sum+=$3}END{ave=sum/NR}END{print ave}' coriolis_data 
0.885491 // WRONG. 
$ awk '{if ($0 ~ /^[[:space:]]*#/){NR--}else{sum+=$3}}END{ave=sum/NR}END{print ave}' coriolis_data 
0.97404  // RIGHT. 
6

ist es am besten nicht NR, berührt eine andere Variable zum Zählen der Zeilen verwenden. Diese Version überspringt sowohl Kommentare als auch Leerzeilen.

$ awk '!/^[ \t]*#/&&NF{sum+=$3;++d}END{ave=sum/d;print ave}' file 
0.97404 
3

Ein weiterer Ansatz ist es, eine bedingte Anweisung zu verwenden ...

awk '{ if($1 != "#"){ print $0 } }' coriolis_data 

Was das bedeutet ist awk sagen Linien, deren überspringen erste Eintrag ist #. Dies setzt natürlich voraus, dass der Kommentarkopf # am Anfang eines Kommentars steht.

Verwandte Themen