Mám například textový dokument:
"Hello, I am the janitor and I have a headache The rabbit jumped over the red brick wall"
chci počítat počet polí, ve kterých se vyskytuje podřetězec „on“. Nechci počítat počet „on“ v souboru, pouze počet polí.
Takže pro můj příklad by to mělo vytisknout něco takového:
Number of fields that contain "he" in record #1: 3 Number of fields that contain "he" in record #2: 2
Musí to být skript awk.
Komentáře
- Co jste zatím vyzkoušeli?
- Zkusil jsem následující skript: " {print " Počet polí v záznamu # " NR " obsahující ' he ': " index ($ 0, " he ")} a nefunguje to '. Zkoušel jsem také gsub, ale gsub počítá každý výskyt ' he ', nejen pole, ve kterých ' he ' je nalezen.
- Musíte iterovat přes pole. Toto by vám mělo pomoci.
- Opustili jste unix.stackexchange.com/questions / 550529 / … ?
- @JohnMike také prosím uveďte své pokusy & jejich výsledky do vaší otázky , kde nebudou ' přehlédnuty.
Odpověď
Pole jsou očíslována od 1
a NF
obsahuje jejich počet. Můžeme je tedy iterovat pomocí for (i = 1; i <= NF; i++) { ... }
, přičemž $i
uvnitř smyčky odkazuje na dané pole. (i
je ve skutečnosti pouze číslo pole, potřebujeme operátor $
, abychom získali skutečný obsah pole.)
A pokud jde o zjištění, zda hodnota obsahuje konkrétní podřetězec, je použití regulárního výrazu nejjednodušší. s ~ /foo/
uvidí, zda proměnná s
odpovídá řetězci foo
kdekoli, tj. pokud obsahuje to jako podřetězec. Nyní můžete také chtít porovnat velké písmeno, v takovém případě např. [Ff]
by fungoval místo f
. Skupina závorek [...]
odpovídá kterékoli ze znaků uvnitř.
Samozřejmě budete také potřebovat počítadlo, ale to je snadné, stačí inicializovat proměnnou na nulu před smyčkou (např. count=0
) a přírůstek, pokud existuje shoda (count += 1
).
~ ~
Takže v zásadě je awk skript pro spuštění nějakého kódu pro každý řádek / záznam souboru jen
awk "{ some code }" < filename.txt
Uvnitř blok kódu, smyčka for
se vejde a zabere také blok ve složených závorkách { .. }
.
awk "{ for ( ... ) { some code } }`
A if
funguje podobně,
if (condition) { some code... }
(ve skutečnosti vypadají jen jako for
a if
v jazyce C.)
K oddělení příkazů můžete použít středníky, takže
awk "{ what to do before the loop; for ( ... ) { some code }; what to do after }`
Komentáře
- jak by to ale vypadalo jako kompletní soubor skriptu? I m v úplné ztrátě. Náš profesor o těchto věcech nemluvil. „Opravdu nerad dávám úplné odpovědi na domácí úkoly. To by však mělo být o všech dílech, pokud máte čas pokusit se z nich něco postavit.
- Nemám ' t a normálně nechtěl bych ' požádat o úplné odpovědi, ale obávám se, že bych v této třídě dostal A. Jsem ' jsem přímým studentem a obvykle nemám problém s mými třídami comp sci, ale tento profesor je proslulý očekáváním mimoškolních znalostí. Nikdy předtím jsem nepoužíval unix / linux a ' jsem zde opravdu bojoval. Domácí úkol se skládá z 20 problémů a tyto 3 plus 2 v dalším příspěvku, který jsem vytvořil, jsou jediné, na které ' nemůžu přijít. Dochází mi čas, ' s zítra.
- @JohnMike, zkuste, jestli se vám podaří dát dohromady nějaké kousky?SE naštve interaktivní ladění tam a zpět, ale můžete upravit svůj Q a přidat skript, pokud se dostanete o krok nebo dva vpřed, a pak můžeme vidět, co ' s zátka
- @JohnMike Vzhledem k (a) zde zobrazenému způsobu iterace nad jednotlivými záznamy pomocí smyčky for, (b)
gsub
, které jste vyzkoušeli v váš opuštěný příspěvek může přijmout cíl k výkonu, tj.gsub("he","",$i)
(c) máte základní comp sci pozadí (d) můžete použít online nástroje jako tutorialspoint.com/execute_bash_online.php , abyste si udělali domácí úkol, i když ve svém počítači nemáte linux, pak není žádná silná výmluva, abyste se nepokusili vyřešit svůj domácí úkol pomocí zde uvedené pomoci. Alespoň to zkuste a pomoc dorazí.
Odpovědět
Hotovo skriptem awk
awk -v i="he" "{print "Number of fields that contain" " " i " " gsub("he",$0) " " "in record " NR}" file
výstup
Number of fields that contain he 3 in record 1 Number of fields that contain he 2 in record 2