Wie zähle ich mit einem awk-Skript die Anzahl der Felder, in denen ein Teilstring in einer Datei liegt?

Zum Beispiel habe ich das Textdokument:

"Hello, I am the janitor and I have a headache The rabbit jumped over the red brick wall" 

Ich möchte zählen die Anzahl der Felder, in denen der Teilstring „he“ vorkommt. Ich möchte nicht die Anzahl von „er“ in der Datei zählen, sondern nur die Anzahl der Felder.

In meinem Beispiel sollte also Folgendes ausgedruckt werden:

Number of fields that contain "he" in record #1: 3 Number of fields that contain "he" in record #2: 2 

Es muss sich um ein awk-Skript handeln.

Kommentare

  • Was haben Sie bisher versucht?
  • Ich habe das folgende Skript ausprobiert: " {print " Anzahl der Felder in Datensatz # " NR " enthält ' he ': " index ($ 0, " er ")} und es funktioniert nicht '. Ich habe auch gsub ausprobiert, aber gsub zählt jedes Vorkommen von ' he ', nicht nur die Felder, in denen ' er ' wurde gefunden.
  • Sie müssen die Felder durchlaufen. Dies sollte Ihnen helfen.
  • Haben Sie unix.stackexchange.com/questions aufgegeben? / 550529 / … ?
  • @JohnMike Bitte geben Sie auch Ihre Versuche & deren Ergebnisse in Ihre Frage , wo sie ' nicht übersehen werden.

Antwort

Die Felder sind beginnend mit 1 und NF enthält die Anzahl von ihnen. Wir können sie also mit for (i = 1; i <= NF; i++) { ... } durchlaufen, wobei $i innerhalb der Schleife auf das betreffende Feld verweist. (i ist eigentlich nur die Nummer des Feldes. Wir benötigen den Operator $, um den tatsächlichen Inhalt des Feldes abzurufen.)

Und um herauszufinden, ob ein Wert einen bestimmten Teilstring enthält, ist die Verwendung eines regulären Ausdrucks am einfachsten. s ~ /foo/ würde prüfen, ob die Variable s mit der Zeichenfolge foo übereinstimmt, dh wenn sie enthält es als Teilzeichenfolge. Jetzt möchten Sie möglicherweise auch einen Großbuchstaben finden. In diesem Fall, z. [Ff] würde anstelle von f funktionieren. Die Klammergruppe [...] stimmt mit einem der darin enthaltenen Zeichen überein.

Natürlich benötigen Sie auch einen Zähler, aber das ist einfach, initialisieren Sie einfach eine Variable vor der Schleife auf Null setzen (z. B. count=0) und erhöhen, wenn „sa match“ vorliegt (count += 1).

~ ~

Grundsätzlich ist ein awk-Skript zum Ausführen von Code für jede Zeile / jeden Datensatz einer Datei nur

awk "{ some code }" < filename.txt 

Codeblock, die Schleife for passt und es wird auch ein Block in geschweiften Klammern { .. } verwendet.

awk "{ for ( ... ) { some code } }` 

Und eine if funktioniert ähnlich,

if (condition) { some code... } 

(Sie sehen tatsächlich einfach aus wie for und if in C.)

Und Sie können Semikolons verwenden, um Anweisungen zu trennen, also

awk "{ what to do before the loop; for ( ... ) { some code }; what to do after }` 

Kommentare

  • Wie würde das als vollständige Skriptdatei aussehen? I m mit vollständigem Verlust. Unser Professor hat ' nicht über dieses Zeug gesprochen.
  • @JohnMike, nun, das ' ist genau das Richtige Ich hasse es wirklich, vollständige Antworten auf Hausaufgaben zu geben. Das sollte jedoch ungefähr alle Teile sein, wenn Sie die Zeit haben, etwas daraus zu bauen.
  • Ich ' t und ich normalerweise Ich würde ' nicht nach vollständigen Antworten fragen, aber ich mache mir Sorgen, dass ich in dieser Klasse ein A bekomme. Ich ' bin ein heterosexueller A-Student und habe normalerweise kein Problem mit meinen Comp-Sci-Klassen, aber dieser Professor ist dafür berüchtigt, außerschulisches Wissen zu erwarten. Ich ' habe noch nie zuvor Unix / Linux verwendet, und ich habe hier wirklich Probleme. Die Hausaufgaben bestehen aus 20 Problemen, und diese 3 plus 2 in einem anderen Beitrag, den ich gemacht habe, sind die einzigen, die ich ' nicht herausfinden kann. Ich habe keine Zeit mehr, ' ist bis morgen fällig.
  • @JohnMike, versuchen Sie, ob Sie einige Teile zusammenbringen können?SE ist für interaktives Hin- und Her-Debuggen nicht geeignet, aber Sie können Ihr Q bearbeiten, um ein Skript hinzuzufügen, wenn Sie ein oder zwei Schritte vorwärts kommen, und dann können wir sehen, was ' das ist Stopper
  • @JohnMike In Anbetracht (a) der hier gezeigten Methode zum Durchlaufen der Felder jedes Datensatzes mit der for-Schleife (b) gsub, die Sie ausprobiert haben Ihr verlassener Beitrag kann ein Ziel akzeptieren, das ausgeführt werden soll, dh gsub("he","",$i) (c) Sie haben einen grundlegenden Comp-Sci-Hintergrund (d) Sie können Online-Tools wie tutorialspoint.com/execute_bash_online.php um Ihre Hausaufgaben zu machen, auch wenn Sie kein Linux in Ihrem PC haben, gibt es keine gute Entschuldigung, nicht zu versuchen, Ihre Hausaufgaben mit der hier gegebenen Hilfe zu lösen. Versuchen Sie es zumindest, und es wird Hilfe eintreffen.

Antwort

Fertig mit dem folgenden awk-Skript

awk -v i="he" "{print "Number of fields that contain" " " i " " gsub("he",$0) " " "in record " NR}" file 

Ausgabe

Number of fields that contain he 3 in record 1 Number of fields that contain he 2 in record 2 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.