Hur räknar jag antalet fält där en substring ligger i en fil med hjälp av ett awk-skript?

Till exempel har jag textdokumentet:

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

Jag vill räkna antalet fält där understrängen ”han” förekommer. Jag vill inte räkna antalet ”han” i filen, bara antalet fält.

Så för mitt exempel borde det skriva ut något så här:

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

Det måste vara ett awk-skript.

Kommentarer

  • Vad har du försökt hittills?
  • Jag har provat följande skript: " {print " Antal fält i post # " NR " som innehåller ' he ': " index ($ 0, " han ")} och det fungerar inte '. Jag försökte också gsub, men gsub räknar varje förekomst av ' he ', inte bara fälten där ' han ' finns.
  • Du måste itera över fälten. Detta borde hjälpa dig.
  • Har du övergivit unix.stackexchange.com/questions / 550529 / … ?
  • @JohnMike, sätt dina försök & deras resultat till din fråga , där de inte får se '.

Svar

Fälten är numrerade från 1 och NF innehåller antalet av dem. Så vi kan itera över dem med for (i = 1; i <= NF; i++) { ... }, med $i inuti slingan med hänvisning till det aktuella fältet. (i är faktiskt bara fältets nummer, vi behöver operatören $ för att få det faktiska innehållet i fältet.)

Och när det gäller att hitta om ett värde innehåller en viss delsträng är det enklast att använda en regex. s ~ /foo/ skulle se om variabeln s matchar strängen foo var som helst, dvs om den innehåller det som ett underlag. Nu kanske du också vill matcha en stor bokstav, i vilket fall t.ex. [Ff] skulle fungera istället för f. Parentesgruppen [...] matchar någon av tecknen inuti.

Naturligtvis behöver du också en räknare, men det är enkelt, initialisera bara en variabel till noll före slingan (t.ex. count=0) och öka om det finns en matchning (count += 1).

~ ~

Så i grund och botten är ett awk-skript för att köra någon kod för varje rad / post i en fil bara

awk "{ some code }" < filename.txt 

Inuti kodblock, for slingan passar, och det tar också ett block i parentes { .. }.

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

Och en if fungerar på samma sätt,

if (condition) { some code... } 

(De ser faktiskt bara ut som for och if i C.)

Och du kan använda semikolon för att separera uttalanden, så

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

Kommentarer

  • hur skulle det dock se ut som en komplett skriptfil? I m med fullständig förlust. Vår professor pratade inte ' om det här.
  • @JohnMike, ja, att ' är bara saken , Jag hatar verkligen att ge fullständiga svar för läxor. Det borde dock handla om alla bitar om du har tid att försöka bygga något ur dem.
  • Jag don ' t, och jag brukar skulle inte ' inte be om fullständiga svar, men jag är orolig för att få ett A i den här klassen. Jag ' är en rak student och har vanligtvis inga problem med mina komp sci-klasser, men den här professorn är ökänd för att förvänta sig kunskaper utanför klassen. Jag ' har aldrig använt unix / linux tidigare och jag kämpar verkligen här. Läxorna består av 20 problem, och dessa 3, plus 2 i ett annat inlägg som jag gjorde, är de enda jag kan ' inte räkna ut. Jag har slut på tid, det ' kommer att ske i morgon.
  • @JohnMike, försök om du kan få några bitar tillsammans?SE suger för interaktiv fram och tillbaka felsökning, men du kan redigera din Q för att lägga till ett skript om du får ett steg eller två framåt, och då kan vi se vad ' är stopper
  • @JohnMike Med tanke på (a) det sätt som visas här för att itera över filerna i varje post med hjälp av for loop, (b) gsub som du har försökt i ditt övergivna inlägg kan acceptera ett mål att utföra dvs gsub("he","",$i) (c) du har en grundläggande comp sci-bakgrund (d) du kan använda onlineverktyg som tutorialspoint.com/execute_bash_online.php för att göra dina läxor även om du inte har Linux på din dator, så finns det ingen stark ursäkt för att inte försöka lösa dina läxor med hjälp som ges här. Gör åtminstone ett försök så kommer hjälp fram.

Svar

Gjort med nedanstående awk-skript

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

utdata

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

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *