Jak używając skryptu awk policzyć liczbę pól, w których znajduje się podciąg w pliku?

Na przykład mam dokument tekstowy:

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

Chcę policzyć liczba pól, w których występuje podciąg „on”. Nie chcę zliczać liczby „on” w pliku, tylko liczbę pól.

Na przykład powinien wydrukować coś takiego:

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

To musi być skrypt awk.

Komentarze

  • Czego próbowałeś do tej pory?
  • Wypróbowałem następujący skrypt: " {print " Liczba pól w rekordzie # " NR " zawierające ' he ': " index ($ 0, " he ")} i nie ' t działa. Próbowałem też użyć gsub, ale gsub liczy każde wystąpienie ' he ', a nie tylko pól, w których ' on ' zostanie znaleziony.
  • Musisz iterować po polach. To powinno Ci pomóc.
  • Czy porzuciłeś unix.stackexchange.com/questions / 550529 / … ?
  • @JohnMike również, proszę podać swoje próby & ich wyniki do twojego pytania , gdzie wygrał ' i nie został przeoczony.

Odpowiedź

Pola są numerowane począwszy od 1 i NF zawiera ich liczbę. Możemy więc je iterować za pomocą for (i = 1; i <= NF; i++) { ... }, z $i wewnątrz pętli odnoszącej się do danego pola. (i to właściwie tylko numer pola, potrzebujemy operatora $, aby uzyskać rzeczywistą zawartość pola).

A jeśli chodzi o znajdowanie, czy wartość zawiera określony podciąg, najłatwiej jest użyć wyrażenia regularnego. s ~ /foo/ sprawdzi, czy zmienna s pasuje do ciągu foo w dowolnym miejscu, tj. jeśli zawiera jako podciąg. Teraz możesz również chcieć dopasować dużą literę, w takim przypadku np. [Ff] będzie działać zamiast f. Grupa nawiasów [...] pasuje do dowolnego ze znaków w środku.

Oczywiście będziesz też potrzebować licznika, ale to proste, po prostu zainicjalizuj zmienną do zera przed pętlą (np. count=0) i zwiększaj, jeśli istnieje „dopasowanie (count += 1).

~ ~

Zasadniczo skrypt awk do uruchomienia kodu dla każdej linii / rekordu pliku to po prostu

awk "{ some code }" < filename.txt 

Wewnątrz bloku kodu, pętla for pasuje, a także przyjmuje blok w nawiasach klamrowych { .. }.

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

A if działa podobnie,

if (condition) { some code... } 

(W rzeczywistości wyglądają po prostu np. for i if w C.)

I możesz używać średników do oddzielania instrukcji, więc

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

Komentarze

  • jak by to wyglądało jako kompletny plik skryptu? I m przy całkowitej stracie. Nasz profesor nie ' nie mówił o tych rzeczach.
  • @JohnMike, cóż, to ' to tylko rzecz , Naprawdę nienawidzę udzielać pełnych odpowiedzi za pracę domową. Powinno to jednak dotyczyć wszystkich elementów, jeśli masz czas, aby spróbować coś z nich zbudować.
  • Nie ' t, i zwykle nie prosiłbym ' o udzielenie pełnych odpowiedzi, ale martwię się, że dostanę szóstkę w tej klasie. Jestem ' prostym uczniem i zwykle nie mam problemu z moimi zajęciami informatycznymi, ale ten profesor znany jest z tego, że oczekuje wiedzy spoza zajęć. ' nigdy wcześniej nie korzystałem z Uniksa / Linuksa i naprawdę mam tutaj problemy. Zadanie domowe składa się z 20 zadań, a te 3 plus 2 w innym poście, które stworzyłem, są jedynymi, których ' nie mogę rozwiązać. Kończy mi się czas, termin ' upływa jutro.
  • @JohnMike, spróbuj, czy uda Ci się zebrać kilka elementów?SE jest do bani w interaktywnym debugowaniu tam i z powrotem, ale możesz edytować swój Q, aby dodać skrypt, jeśli zrobisz krok lub dwa do przodu, a wtedy zobaczymy, co ' jest stopper
  • @JohnMike Biorąc pod uwagę (a) pokazany tutaj sposób iteracji plików każdego rekordu za pomocą pętli for, (b) gsub, który próbowałeś Twój porzucony post może przyjąć cel do wykonania, np. gsub("he","",$i) (c) masz podstawowe podstawy informatyczne (d) możesz korzystać z narzędzi online, takich jak tutorialspoint.com/execute_bash_online.php , aby odrobić pracę domową, nawet jeśli nie masz Linuksa na swoim komputerze, nie ma żadnej wymówki, aby nie próbować rozwiązać zadania domowego z pomocą podaną tutaj. Przynajmniej spróbuj, a pomoc nadejdzie.

Odpowiedź

Wykonane przez poniższy skrypt awk

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

wyjście

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

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *