v1.1.2 / Кіраўнік 1 з 3 / 01 ліпеня 10 / Greg Гебель / грамадскім здабыткам
* У гэтым раздзеле даецца агляд Awk і кароткі агляд яго выкарыстання.
* Awk апрацоўкі тэкстаў мовы карысна для такіх задач як:
Awk мае два твары: гэта ўтыліта для выканання простых задач апрацоўкі тэксту, і гэта мова праграмавання для выканання складаных для апрацоўкі тэксту задач.
Два асобы на самай справе ж, аднак. Awk выкарыстоўвае тыя ж механізмы для апрацоўкі любы тэкст апрацоўкі задач, але гэтыя механізмы з'яўляюцца дастаткова гнуткімі, каб дазволіць карысныя праграмы Awk быць уведзены ў камандным радку, або для рэалізацыі складаных праграм, якія змяшчаюць дзясяткі радкоў заявы AWK.
Awk справаздачнасць ўключае мова праграмавання. На самай справе, Awk карысна для простай, хуткі і брудны вылічальных праграм. Любы, хто можа напісаць праграму BASIC можна выкарыстоўваць Awk, хоць сінтаксіс Awk з'яўляецца адрозніваецца ад BASIC. Любы, хто можа напісаць праграму на З, можна выкарыстоўваць Awk без асаблівых цяжкасцяў, і тыя, хто хацеў бы вывучаць З можа знайсці Awk карысна прыступку - з асцярогай, што Awk і З маюць значныя адрозненні за межамі іх шмат агульнага.
Ёсць, аднак, рэчы, якія Awk гэта не так. Гэта не вельмі добра падыходзіць для вельмі вялікіх, складаных задач. Акрамя таго, "інтэрпрэтаваць" мова - гэта значыць, праграма Awk не можа працаваць сама па сабе, яна павінна быць выканана з дапамогай утыліты Awk сябе. Гэта азначае, што ён адносна павольна, хоць гэта з'яўляецца эфектыўным, як інтэрпрэтацыі моў ісці, і што праграма можа быць выкарыстаная толькі ў сістэмах, якія маюць Awk. Ёсць перакладчыкі, якія могуць пераўтварыць Awk праграм у код C для кампіляцыі ў якасці самастойных праграм, але такія перакладчыкі павінны быць набыты асобна.
Апошні пункт да судовага разбору: Што азначае назва "Awk" азначае? Awk фактычна азначае імёны яе аўтараў: "Ахо, Уайнбергер, і Керниган". Керниган пазней адзначыў: "Найменне мову пасля яго аўтараў ... паказвае пэўныя беднасці ўяўлення." Назва нагадвае, што ў акіянічных птушак вядомыя як "АУК", і таму карціна AUK часта з'яўляецца на вокладцы кнігі па AWK.
* Гэта просты ў выкарыстанні Awk з каманднага радка для выканання простых аперацый над тэкставымі файламі. Няхай у нас ёсць файл з назвай "coins.txt", які апісвае Калекцыя манет. Кожная радок у файле ўтрымліваецца наступная інфармацыя:
metal weight in ounces date minted country of origin descriptionThe file has the contents:
gold 1 1986 USA American Eagle gold 1 1908 Austria-Hungary Franz Josef 100 Korona silver 10 1981 USA ingot gold 1 1984 Switzerland ingot gold 1 1979 RSA Krugerrand gold 0.5 1981 RSA Krugerrand gold 0.1 1986 PRC Panda silver 1 1986 USA Liberty dollar gold 0.25 1986 USA Liberty 5-dollar piece silver 0.5 1986 USA Liberty 50-cent piece silver 1 1987 USA Constitution dollar gold 0.25 1987 USA Constitution 5-dollar piece gold 1 1988 Canada Maple LeafТады мы маглі б спасылацца Awk да спісу ўсіх залатых наступным чынам:
awk '/gold/' coins.txtГэта кажа Awk для пошуку праз файл для радкоў тэксту, якія ўтрымліваюць радок "золата", і раздрукаваць іх. У выніку:
gold 1 1986 USA American Eagle gold 1 1908 Austria-Hungary Franz Josef 100 Korona gold 1 1984 Switzerland ingot gold 1 1979 RSA Krugerrand gold 0.5 1981 RSA Krugerrand gold 0.1 1986 PRC Panda gold 0.25 1986 USA Liberty 5-dollar piece gold 0.25 1987 USA Constitution 5-dollar piece gold 1 1988 Canada Maple Leaf* Усё гэта вельмі міла, крытык можа сказаць, але любы "GREP" альбо "знайсьці" утыліта можа рабіць тое ж самае. Гэта праўда, але Awk здольны рабіць многае іншае. Напрыклад, выкажам здагадку, мы толькі хочам, каб раздрукаваць апісанне поля, і пакінуць усё іншыя з тэксту. Тады мы маглі б змяніць выклік Awk для:
awk '/gold/ {print $5,$6,$7,$8}' coins.txt
Гэта дае:
American Eagle Franz Josef 100 Korona ingot Krugerrand Krugerrand Panda Liberty 5-dollar piece Constitution 5-dollar piece Maple LeafГэты прыклад дэманструе найпросты агульны выгляд праграмы Awk:
awk <search pattern> {<program actions>}
Awk праглядае ўваходны файл для кожнай лініі, які ўтрымлівае шаблён пошуку. Для кожнай з гэтых ліній знойдзены, Awk затым выконвае пэўныя дзеянні. У гэтым прыкладзе, дзеянне вызначаецца як:
{print $5,$6,$7,$8}
Мэта "друку" зацвярджэнне відавочна. "$ 5", "$ 6", "$ 7", і "$ 8" "палёў", або "палі зменных", якія захоўваюць слова ў кожнай радку тэксту іх лікавыя паслядоўнасці. "$ 1", напрыклад, крамы першае слова ў радку, "$ 2" па-другое, і гэтак далей. Па змаўчанні, "слова" вызначаецца як любая радок друку сімвалаў, падзеленых прабеламі. Так як "coins.txt" мае структуру:
metal weight in ounces date minted country of origin description- Гэта поле зменных супастаўляюцца з кожнай радкі тэксту ў файл наступным чынам:
metal: $1 weight: $2 date: $3 country: $4 description: $5 through $8Праграма дзеянняў у гэтым прыкладзе друкуецца поля, якія змяшчаюць апісанне. Апісанне поля ў файл можа фактычна ўключаць ад аднаго да чатырох палёў, але гэта не праблема, бо "друк" проста ігнаруе любыя нявызначаныя поля. Уважлівы чытач заўважыць, што "coins.txt" файл акуратна арганізаваны так, што толькі частка інфармацыі, якая ўтрымлівае некалькі палёў у канцы лініі. Гэта крыху надуманы, але гэта шлях прыкладаў.
праграмы па змоўчанні * Awk ў дзеянне для друку ўсёй лініі, што і "друку" не пры выкліку без параметраў. Гэта азначае, што першы прыклад:
awk '/gold/'-- такая ж, як:
awk '/gold/ {print}'
Звярніце ўвагу, што Awk прызнае поле зменнай $ 0, якія прадстаўляюць ўсю лінію, так што гэта можа быць запісаны як:
awk '/gold/ {print $0}'
This is redundant, but it does have the virtue of making the action more
obvious.
* Хай зараз мы хочам, каб пералічыць усе манеты, якія чаканіліся да 1980 года. Мы спасылацца Awk наступным чынам:
awk '{if ($3 < 1980) print $3, " ",$5,$6,$7,$8}' coins.txt
Гэта дае:
1908 Franz Josef 100 Korona 1979 KrugerrandГэта новы прыклад дадае некалькі новых паняццяў:
Там у тонкі пытанне удзел тут, аднак. У большасці моў праграмавання, радкі радкі, і лічбы нумара. Ёсць аперацыі, якія унікальныя для кожнага, і трэба быць канкрэтна ператвораныя ў іншыя з пераўтварэннем функцый - мы не аб'яднаць нумары, і мы не выканання арыфметычных аперацый над радкамі.
Awk, з другога боку, не дае моцнае адрозненне паміж радкамі і лікамі. У кампутарнай навуцы тэрміны, гэта "слаба типизированный" мовы. Усе палі разглядаюцца як радкі, але калі гэты радок таксама адбываецца прадстаўляць чысла, лікавыя аперацыі могуць быць выкананы на ім. Так што мы можам выконваць арыфметычныя параўнання на поле даты.
* Наступны прыклад выводзіць колькі манет у калекцыі:
awk 'END {print NR,"coins"}' coins.txt
Гэта дае:
13 coinsПершы новы пункт у гэтым прыкладзе END заяву. Для тлумачэння гэтага патрабуе пашырэння агульны выгляд праграмы Awk для:
awk 'BEGIN {<initializations>}
<search pattern 1> {<program actions>}
<search pattern 2> {<program actions>}
...
END {<final actions>}'
Прапанова BEGIN выконвае любыя ініцыялізацыі патрабуецца да Awk пачынае сканіраванне ўваходнага файла. Наступныя целе праграмы Awk складаецца з серыі шаблонаў пошуку, кожны са сваёй уласнай праграмы дзеянняў. Awk сканіраванне кожнага радка ўваходнага файла для кожнага шаблон пошуку, і выконвае адпаведныя дзеянні для кожнай радкі знойдзены. Пасля таго як файл быў прасканаваў, прапанова канец можа быць выкарыстаны для выканання любога дзеяння, неабходныя канчатковае. Так што гэта прыклад не выконвае ніякай апрацоўкі на ўваходных ліній сябе. Усё гэта з'яўляецца сканіраванне файлаў і выканаць канчатковае рашэнне: друку колькасць радкоў у файле, які даецца "NR" зменнай. NR расшыфроўваецца як "колькасць запісаў". NR з'яўляецца адным з "наканаванага" Awk ў пераменныя. Ёсць і іншыя, напрыклад пераменная NF дае лік палёў у радку, але падрабязнае тлумачэнне прыйдзецца чакаць на потым.
* Хай бягучы кошт золата складае $ 425, і мы хочам, каб высветліць прыблізны агульны кошт залатых манет у калекцыі манет. Мы спасылацца Awk наступным чынам:
awk '/gold/ {ounces += $2} END {print "value = $" 425*ounces}' coins.txt
Гэта дае:
value = $2592.5У гэтым прыкладзе, "унцый" з'яўляецца "карыстальнікам" зменнай, у адрозненне ад "стандартнага" наканаваных пераменных. Амаль любая радок знакаў можа быць выкарыстана як імя зменнай у Awk тых часоў, пакуль імя не канфліктуе з некаторымі радок, якая мае асаблівае значэнне для Awk, такіх як "друк" або "NR" ці "END". Існуе не трэба абвясціць зменную, або для яго ініцыялізацыі. Пераменная апрацоўваецца як радковыя пераменная ініцыялізуецца «пустая радок", што азначае, што калі мы будзем спрабаваць надрукаваць яго, нічога не будзе. Пераменная апрацоўваецца як лічбавая пераменная будзе абнулены.
Так, праграма дзеянняў:
{ounces += $2}
-- сумы вага кавалка на кожнай знойдзенай радкі ў зменнай "унцыі". Тыя, хто праграму ў C павінны быць знаёмыя з "+ =" аператара. Тыя, хто не можа быць упэўнены, што гэта проста скарочаны спосаб сказаць:
{ounces = ounces + $2}
Канчатковае рашэнне з'яўляецца для разліку і друку значэнне золата:
END {print "value = $" 425*ounces}
Адзінае тут цікавасць у тым, што дзве параметраў друку, літаральнае "значэнне = $" "і выраз" 425 * унцый ", падзеленых прасторай, а не коска. Гэта аб'ядноўвае два параметра разам на выхадзе, без якіх-небудзь прабелаў.
* Усё гэта весела, але кожны з гэтых прыкладаў толькі здаецца, каб грызці прэч на "coins.txt". Чаму б не Awk высветліць усё цікавае ў адзін час?
Неадкладна пярэчанняў супраць гэтай ідэі з'яўляецца тое, што было б немэтазгодна ўводзіць шмат заяваў Awk ў камандным радку, але гэта лёгка выправіць. Каманды могуць быць запісаны ў файл, а затым Awk можа быць загадана выконваць каманды з гэтага файла наступным чынам:
awk -f <awk program file name>Улічваючы магчымасць пісаць праграмы Awk такім чынам, тое, што павінна "Майстар" "coins.txt" Аналіз праграмы рабіць? Вось адзін з магчымых выхаду:
Summary Data for Coin Collection:
Gold pieces: nn
Weight of gold pieces: nn.nn
Value of gold pieces: n,nnn.nn
Silver pieces: nn
Weight of silver pieces: nn.nn
Value of silver pieces: n,nnn.nn
Total number of pieces: nn
Value of collection: n,nnn.nn
Наступная праграма Awk спараджае наступную інфармацыю:
# This is an awk program that summarizes a coin collection.
#
/gold/ { num_gold++; wt_gold += $2 } # Get weight of gold.
/silver/ { num_silver++; wt_silver += $2 } # Get weight of silver.
END { val_gold = 485 * wt_gold; # Compute value of gold.
val_silver = 16 * wt_silver; # Compute value of silver.
total = val_gold + val_silver;
print "Summary data for coin collection:"; # Print results.
printf ("\n");
printf (" Gold pieces: %2d\n", num_gold);
printf (" Weight of gold pieces: %5.2f\n", wt_gold);
printf (" Value of gold pieces: %7.2f\n",val_gold);
printf ("\n");
printf (" Silver pieces: %2d\n", num_silver);
printf (" Weight of silver pieces: %5.2f\n", wt_silver);
printf (" Value of silver pieces: %7.2f\n",val_silver);
printf ("\n");
printf (" Total number of pieces: %2d\n", NR);
printf (" Value of collection: %7.2f\n", total); }
Гэтая праграма мае некалькі цікавых асаблівасцяў: printf("<format_code>",<parameters>)
Існуе адзін фармат кода для кожнага з параметраў у спісе. Кожны фармат код вызначае, як адпаведны параметр будзе надрукаваны. Напрыклад, код фармату "% 2d" распавядае Awk для друку двухзначны цэлы лік, і код фармату "% 7.2f" распавядае Awk для друку сямізначны ліку з якая плавае кропкай, з двума лічбамі справа ад дзесятковай кропкі.
Адзначым таксама, што ў гэтым прыкладзе, кожны радок надрукаваны "Е" заканчваецца "\ п", які з'яўляецца кодам для "новай радкі" (ASCII перакладу радкі кода). У адрозненне ад "друку" заяву, якое аўтаматычна дасягненняў выхад на наступны радок пры друку лініі, "Е" не аўтаматычна загадзя выхад, і па змаўчанні наступнае сцвярджэнне выхад будзе дадаваць сваю прадукцыю да той жа лініі. Радкі сілы выхаду для пераходу да наступнай радку.
* Гэтая праграма можа быць захавана ў файл з імем "summary.awk", і выклікаецца наступным чынам:
awk -f summary.awk coins.txtВыхад:
Summary data for coin collection:
Gold pieces: 9
Weight of gold pieces: 6.10
Value of gold pieces: 2958.50
Silver pieces: 4
Weight of silver pieces: 12.50
Value of silver pieces: 200.00
Total number of pieces: 13
Value of collection: 3158.50
* Гэтая інфармацыя дае досыць фоне добра выкарыстоўваць AWK. Наступная кіраўнік значна больш поўнае апісанне мовы.