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