<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF138%3ADrBrown2</id>
		<title>LXF138:DrBrown2 - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF138%3ADrBrown2"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF138:DrBrown2&amp;action=history"/>
		<updated>2026-05-13T03:53:20Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF138:DrBrown2&amp;diff=13373&amp;oldid=prev</id>
		<title>Crazy Rebel: викификация¸оформление, иллюстрация</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF138:DrBrown2&amp;diff=13373&amp;oldid=prev"/>
				<updated>2012-02-16T08:51:43Z</updated>
		
		<summary type="html">&lt;p&gt;викификация¸оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==''Awk'' в при­ме­рах==&lt;br /&gt;
&lt;br /&gt;
: ''Awk'' не обя­зан быть не­ук­лю­жим. По­учим­ся у од­но­строч­ни­ков-ве­те­ра­нов.&lt;br /&gt;
&lt;br /&gt;
Я немно­го вол­ну­юсь, по­то­му что наш урок бу­дет про язык про­грам­ми­ро­вания. Мож­но ли это счи­тать «ад­минист­ри­ро­ванием»? Ну, во­об­ще-то лю­бой ува­жаю­щий се­бя си­с­ад­мин дол­жен об­ла­дать ба­зо­вы­ми знания­ми по про­грам­ми­ро­ванию. На­вер­ное, са­мый по­пу­ляр­ный язык про­грам­ми­ро­вания для ад­минист­ра­то­ров – сце­на­рии обо­лоч­ки, но ду­маю, что ''Awk'' идет за ним по пя­там. Во вся­ком слу­чае, в этом ме­ся­це я но­миниро­вал ''Awk'' на звание по­чет­но­го ин­ст­ру­мен­та администрирования.&lt;br /&gt;
&lt;br /&gt;
Скрип­то­вый язык ''Awk'' на­зван по пер­вым бу­к­вам фа­ми­лий его соз­да­те­лей: Альф­ре­да Ахо [Alfred Aho], Пи­те­ра Вайн­бер­ге­ра [Peter Weinberger] и Брай­а­на Кернига­на [Brian Kernighan]. В ва­шем ди­ст­ри­бу­ти­ве ско­рее все­го бу­дет ''GAwk'' (‘G’ от ‘GNU’), пе­репи­сан­ная вер­сия ис­ход­но­го ''Awk'' – на­до ли го­во­рить, что рас­ши­ренн­ная. ''Awk'' пре­крас­но под­хо­дит для об­ра­бот­ки дан­ных, раз­би­тых на стро­ки, в ка­ж­дой из ко­то­рых есть по­ля, на­при­мер, дан­ные, раз­де­лен­ные на стро­ки и столб­цы. В Linux та­ких при­ме­ров мно­же­ство – фай­лы '''/etc/passwd, /etc/fstab, /etc/hosts''' и т. д. или вы­вод та­ких ко­манд, как ''df, ps -ef'' или ''ls -l'', или ре­зуль­тат экс­пор­та элек­трон­ной таб­ли­цы в файл '''CSV''' (зна­чений, раз­де­лен­ных за­пя­ты­ми). По су­ти, ''Awk'' – свое­об­раз­ный эк­ви­ва­лент элек­трон­ной таб­ли­цы в команд­ной стро­ке. Ну, нечто вро­де это­го. ''Awk'' при­ме­ня­ет­ся для обоб­щения и пе­ре­фор­ма­ти­ро­вания вы­во­да ка­кой-то дру­гой про­грам­мы, пре­об­ра­зо­вания фор­ма­та вы­во­да про­грам­мы A во вход­ной фор­мат про­грам­мы B, про­вер­ки дан­ных... и да­же как язык про­грам­ми­ро­вания об­ще­го на­зна­чения.&lt;br /&gt;
&lt;br /&gt;
===Срав­не­ние ''Awk'' и ''C''===&lt;br /&gt;
&lt;br /&gt;
Стран­но, ко­неч­но, со­пос­тав­лять Мо Мо­улем [Mo Mowlam] и Кар­лу Сар­ко­зи [Carla Sarkozy], но на ''Awk'' не­со­мнен­но по­вли­ял ''C''. Их ариф ме­ти­че­ские опе­ра­ции и опе­ра­ции срав­не­ния очень по­хо­жи. В ''Awk'' есть вы­ра­же­ния '''if, else, for, break''' и '''continue''', ко­то­рые оз­на­ча­ют то же са­мое, что в ''C''. Но в ''Awk'' нет ста­ти­че­ской ти­пи­за­ции, как в ''C'', и пе­ре­мен­ные не нуж­но объ­яв­лять до их ис­поль­зо­ва­ния; а есть встро­ен­ная про­вер­ка на со­от­вет­ст­вие ре­гу­ляр­ным вы­ра­же­ни­ям, от­сут­ст­вую­щая в ''C''. И го­то­вый ме­ха­низм ''Awk'' «про­чи­тать стро­ку вво­да и раз­бить ее на по­ля» в ''C'' нуж­но реа­ли­зо­вы­вать са­мо­стоя­тель­но.&lt;br /&gt;
&lt;br /&gt;
===Раз­бор стро­ки за стро­кой===&lt;br /&gt;
&lt;br /&gt;
Пол­ное опи­сание ''Awk'' не уме­стит­ся в три страницы, и я по­ста­ра­юсь дать вам пред­став­ление об его воз­мож­но­стях на при­ме­рах. В клас­си­че­ском смыс­ле Unix, ''Awk'' – фильтр, по­сколь­ку счи­ты­ва­ет ис­ход­ный файл, ес­ли он ука­зан, или стан­дарт­ный ввод, ес­ли нет, и его мож­но ис­поль­зо­вать в ка­на­лах. Основ­ная за­да­ча ''Awk'' – стро­ка за стро­кой чи­тать вход­ные дан­ные и раз­би­вать ка­ж­дую стро­ку на по­ля.&lt;br /&gt;
&lt;br /&gt;
В про­грам­ме на ''Awk'' доступ к по­лям мож­но по­лу­чить с по­мо­щью обо­зна­чений '''$1, $2''' и т. д. Обо­зна­чение '''$0''' ссыла­ет­ся на всю стро­ку. Для это­го не нуж­но пи­сать ни строч­ки ко­да – это часть внут­реннего ме­ханиз­ма ''Awk''. Од­но из про­стей­ших при­менений ''Awk'' – фильт­ро­вать и пе­ре­фор­ма­ти­ро­вать вы­вод дру­гих ко­манд. Вот при­мер пе­ре­на­прав­ления вы­во­да коман­ды ''df'' в ''Awk'':&lt;br /&gt;
&lt;br /&gt;
 $ df | awk ‘ /^\/dev/ { print $1 “: “ $5 }’&lt;br /&gt;
 /dev/sda6: 56%&lt;br /&gt;
 /dev/sdb1: 10%&lt;br /&gt;
 /dev/sda3: 40%&lt;br /&gt;
&lt;br /&gt;
Здесь мы ве­ле­ли ''Awk'' вы­брать стро­ки, на­чи­наю­щие­ся с '''/dev''', и вы­вести их пер­вое и пя­тое по­ля.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF138_49_1.jpg|300px]] Шаб­ло­ны при­ме­ня­ют­ся для фильт­ра­ции строк на ос­но­ве фак­то­ров ти­па про­вер­ки зна­че­ния по­ля.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Бо­лее длин­ные про­грам­мы удобнее по­ме­щать в от­дель­ный файл. В сле­дую­щем при­ме­ре мы от­сканиру­ем файл па­ро­лей в по­исках наи­боль­ше­го иден­ти­фи­ка­то­ра поль­зо­ва­те­ля. Вот про­грам­ма – я на­звал ее '''maxuid.awk''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcal lang=awk&amp;gt;&lt;br /&gt;
 BEGIN { FS = “:” ; maxuid = 0 }&lt;br /&gt;
 $3 &amp;gt; maxuid { maxuid = $3 ; maxname = $1 }&lt;br /&gt;
 END { print maxname “: “ maxuid }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В ко­манд­ной стро­ке ее мож­но за­пус­тить, ука­зав файл скрип­та с клю­чом '''-f''':&lt;br /&gt;
&lt;br /&gt;
 $ awk -f maxuid.Awk /etc/passwd&lt;br /&gt;
 nobody: 65534&lt;br /&gt;
&lt;br /&gt;
Раз­бе­рем эту про­грам­му. Как и все сце­на­рии ''Awk'', она со­сто­ит из пар «шаб­лон–дей­ствие». Шаб­ло­ны вы­би­ра­ют стро­ки, над ко­то­ры­ми нуж­но вы­полнить дей­ствия, а дей­ствия оп­ре­де­ля­ют, что с ними де­лать. Осо­бые шаб­ло­ны '''BEGIN''' и '''END''' по­зво­ля­ют за­дать дей­ствия, вы­пол­няе­мые пе­ред об­ра­бот­кой пер­вой стро­ки или по­сле об­ра­бот­ки по­следней.&lt;br /&gt;
&lt;br /&gt;
===На­ча­ло, се­ре­ди­на и конец===&lt;br /&gt;
&lt;br /&gt;
Шаб­ло­ны '''BEGIN''' обыч­но ис­поль­зу­ют­ся для инициа­ли­за­ции пе­ре­мен­ных. В дан­ном слу­чае, мы уста­нав­ли­ва­ем пе­ре­мен­ную раз­де­ли­те­ля по­ля '''FS''' в ''':''', по­то­му что имен­но так раз­де­ле­ны по­ля в фай­ле па­ро­лей. (По умол­чанию в ка­че­стве раз­де­ли­те­ля ис­поль­зу­ют­ся про­бе­лы.) Шаб­лон '''END''' часто ис­поль­зу­ет­ся для вы­во­да ре­зуль­та­тов, как мы и сде­ла­ли в этом при­ме­ре. Сред­няя стро­ка вы­пол­ня­ет об­ра­бот­ку. Она го­во­рит: «Ес­ли третье по­ле боль­ше, чем са­мый боль­шой иден­ти­фи­ка­тор, ко­то­рый мы ви­де­ли до сих пор ('''maxuid'''), об­но­вить зна­чение '''maxuid''' и за­помнить свя­зан­ное с ним имя поль­зо­ва­те­ля».&lt;br /&gt;
&lt;br /&gt;
Но есть и бо­лее про­стой спо­соб за­пустить про­грам­му. Ес­ли до­ба­вить в на­ча­ло скрип­та ком­би­на­цию сим­во­лов '''#!''' и сде­лать его ис­пол­няе­мым, мож­но за­пустить его как коман­ду, точ­но так же, как сце­на­рий обо­лоч­ки. Тогда наш скрипт бу­дет вы­гля­деть так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
 #!/usr/bin/awk -f&lt;br /&gt;
 BEGIN { FS = “:” ; maxuid = 0 }&lt;br /&gt;
 $3 &amp;gt; maxuid { maxuid = $3 ; maxname = $1 }&lt;br /&gt;
 END { print maxname “: “ maxuid }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пра­ва на вы­пол­не­ние мож­но вы­дать та­ким об­ра­зом:&lt;br /&gt;
&lt;br /&gt;
 $ chmod u+x maxuid.Awk&lt;br /&gt;
&lt;br /&gt;
За­тем мож­но об­ра­тить­ся к про­грам­ме по име­ни, как к ко­ман­де:&lt;br /&gt;
&lt;br /&gt;
 $ ./maxuid.awk /etc/passwd&lt;br /&gt;
 nobody: 65534&lt;br /&gt;
&lt;br /&gt;
Шаб­лон или дей­ст­вие в вы­ра­же­нии ''Awk'' не­обя­за­тель­ны. Ес­ли нет шаб­ло­на, дей­ст­вие вы­пол­ня­ет­ся над ка­ж­дой стро­кой, а ес­ли не ука­за­но дей­ст­вие, ''Awk'' про­сто вы­во­дит стро­ку.&lt;br /&gt;
&lt;br /&gt;
В оче­ред­ном при­ме­ре есть шаб­лон, но нет дей­ст­вия. Он по­ка­зы­ва­ет все учет­ные за­пи­си в '''/etc/passwd''' с UID 1000 или вы­ше:&lt;br /&gt;
&lt;br /&gt;
 $ awk -F: ‘$3 &amp;gt;= 1000’ /etc/passwd&lt;br /&gt;
&lt;br /&gt;
А в этом при­ме­ре есть дей­ст­вие, но нет шаб­ло­на – он про­сто вы­во­дит все име­на поль­зо­ва­те­лей из '''/etc/passwd''':&lt;br /&gt;
&lt;br /&gt;
 $ awk -F: ‘{ print $1 }’ /etc/passwd&lt;br /&gt;
&lt;br /&gt;
Об­ра­ти­те внимание на оп­цию '''-F:''' она слу­жит для ука­зания раз­де­ли­те­ля по­лей. Это аль­тер­на­ти­ва яв­но­му при­своению раз­де­ли­те­ля пе­ре­мен­ной '''FS''' из на­ших пре­ды­ду­щих при­ме­ров.&lt;br /&gt;
&lt;br /&gt;
Ча­стью сво­ей мо­щи ''Awk'' обя­зан ог­ром­но­му ко­ли­че­ству ве­щей, до­пусти­мых в ка­че­стве шаб­ло­на, т. е. воз­мож­но­сти вы­брать стро­ки, над ко­то­ры­ми бу­дет вы­полнено дей­ствие.&lt;br /&gt;
&lt;br /&gt;
===В од­ну стро­ку===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF138_50_1.jpg|300px]] Про­грам­мы на ''Awk'' счи­ты­ва­ют вход­ные дан­ные стро­ка за стро­кой, раз­би­вая их на по­ля. Встро­ен­ные пе­ре­мен­ные '''NR''' и '''NF''' со­дер­жат но­мер за­пи­си и чис­ло по­лей.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Как вы уви­ди­те, про­грам­мам на ''Awk'' не обя­за­тель­но быть длин­ны­ми, что­бы быть по­лез­ны­ми. Я бы пред­по­ло­жил (это толь­ко до­гад­ка), что в среднеста­ти­сти­че­ской про­грам­ме не боль­ше 10 строк. Вот еще несколь­ко од­но­строч­ных про­грамм. В ка­ж­дом слу­чае при­ве­де­на имен­но про­грам­ма, а не вся команд­ная стро­ка.&lt;br /&gt;
&lt;br /&gt;
Вы­вес­ти ка­ж­дую де­ся­тую стро­ку:&lt;br /&gt;
&lt;br /&gt;
 NR%10 == 0&lt;br /&gt;
&lt;br /&gt;
Про­ну­ме­ро­вать стро­ки в вы­во­де:&lt;br /&gt;
&lt;br /&gt;
 { print NR, $0 }&lt;br /&gt;
&lt;br /&gt;
Вы­вес­ти вход­ные стро­ки в об­рат­ном по­ряд­ке:&lt;br /&gt;
&lt;br /&gt;
 { s = $0 “\n” s } END { print s }&lt;br /&gt;
&lt;br /&gt;
Вы­вес­ти стро­ки, вы­ров­нен­ные по цен­тру (по столб­цу 40):&lt;br /&gt;
&lt;br /&gt;
 { printf “%” int(40+length($0)/2) “s\n”, $0 }&lt;br /&gt;
&lt;br /&gt;
Вы­вес­ти не­пус­тые стро­ки:&lt;br /&gt;
&lt;br /&gt;
 NF&lt;br /&gt;
&lt;br /&gt;
Да, это за­кон­чен­ная про­грам­ма! Воз­мож­но, здесь нуж­но по­яснение. '''NF''' (чис­ло по­лей) – встро­ен­ная пе­ре­мен­ная ''Awk'', ко­то­рая об­нов­ля­ет­ся при ка­ж­дой стро­ке. Ес­ли ее ис­поль­зо­вать как шаб­лон (что мы и сде­ла­ли), то дей­ствие по умол­чанию (вы­вести стро­ку) вы­полнит­ся, ес­ли '''NF''' рав­на TRUE (не ноль).&lt;br /&gt;
&lt;br /&gt;
===Биб­лио­те­ка функ­ций===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF138_50_2.jpg|300px]] Лишь часть функ­ций для об­ра­бот­ки строк в биб­лио­те­ке ''Awk''.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
В ''Awk'' есть ма­лень­кая, но по­лез­ная встро­ен­ная биб­лио­те­ка функ­ций; при необ­хо­ди­мо­сти мож­но оп­ре­де­лить и свои соб­ствен­ные. Как и сле­до­ва­ло ожи­дать, есть мас­са функ­ций для ра­бо­ты со стро­ка­ми. Неко­то­рые из них при­ве­де­ны в таб­ли­це ниже. Так­же есть на­бор ма­те­ма­ти­че­ских функ­ций, вклю­чая '''sin(), cos(), exp(), sqrt()''' и '''rand()'''; по­след­няя пред­став­ля­ет со­бой генера­тор слу­чай­ных чи­сел.&lt;br /&gt;
&lt;br /&gt;
Вот еще несколь­ко про­грамм в од­ну стро­ку, ис­поль­зую­щих встро­ен­ные функ­ции:&lt;br /&gt;
&lt;br /&gt;
Вы­вес­ти стро­ки, ко­то­рые длин­нее 80 сим­во­лов:&lt;br /&gt;
&lt;br /&gt;
 length($0) &amp;gt; 80&lt;br /&gt;
&lt;br /&gt;
Этот при­мер ме­ня­ет '''TTY''' на '''TERMINAL''', но толь­ко в пер­вой стро­ке. Фраг­мент '''NR!=1''' в кон­це – вто­рой шаб­лон, бла­го­да­ря ко­то­ро­му ос­таль­ные стро­ки вы­во­дят­ся без из­ме­не­ний:&lt;br /&gt;
&lt;br /&gt;
 NR==1 { gsub(“TTY”, “TERMINAL”); print } NR!=1&lt;br /&gt;
&lt;br /&gt;
Обыч­ное по­ве­де­ние ''Awk'' – счи­тать ка­ж­дую вход­ную стро­ку от­дель­ной за­пи­сью, но ино­гда за­пи­си бы­ва­ют и в не­сколь­ко строк. На­при­мер, в сле­дую­щем фай­ле со­дер­жат­ся две за­пи­си по три стро­ки (имя, род­ной го­род, имя же­ны), раз­де­лен­ные про­бе­лами:&lt;br /&gt;
&lt;br /&gt;
 Homer Simpson&lt;br /&gt;
 Springfield&lt;br /&gt;
 Marge&lt;br /&gt;
&lt;br /&gt;
 Fred Flintstone&lt;br /&gt;
 Bedrock&lt;br /&gt;
 Wilma&lt;br /&gt;
&lt;br /&gt;
Что­бы об­ра­бо­тать эти дан­ные, нуж­но из­ме­нить и раз­де­ли­тель по­лей ('''FS'''), и раз­де­ли­тель за­пи­сей ('''RS''') в ''Awk''. На­при­мер, сле­дую­щая про­грам­ма по­ка­зы­ва­ет жен всех жи­те­лей Бед­ро­ка. Фо­кус в том, что раз­де­ли­тель строк нуж­но ус­та­но­вить в '''null''' (пус­тая стро­ка):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
 BEGIN { RS = “” ; FS = “\n” }&lt;br /&gt;
 $2 == “Bedrock” { print $3 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Идем впе­ред===&lt;br /&gt;
&lt;br /&gt;
Вот при­мер под­лин­нее. Вы­вод ко­ман­ды ''ps -ef'' со­сто­ит из строк сле­дую­ще­го фор­ма­та:&lt;br /&gt;
&lt;br /&gt;
 chris 3014 1 0 Aug17 ? 00:01:19 gedit&lt;br /&gt;
&lt;br /&gt;
Седь­мое по­ле со­дер­жит вре­мя ра­бо­ты про­цес­са в фор­ма­те '''ЧЧ:ММ:СС''', и на­ша за­да­ча – пре­об­ра­зо­вать его в це­лое чис­ло се­кунд. Для это­го его нуж­но раз­бить на три по­ля и сно­ва со­брать их, вы­пол­нив со­от­вет­ст­вую­щие ариф­ме­ти­че­ские дей­ст­вия. Вот про­грам­ма на ''Awk'': '''seconds.awk'''. Она со­дер­жит един­ст­вен­ное дей­ст­вие без шаб­ло­на (по­это­му оно при­ме­ня­ет­ся к ка­ж­дой стро­ке):&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF138_51_1.jpg|300px]] Про­грам­мы на ''Awk'' — на­бор шаб­ло­нов и дей­ст­вий. Шаб­ло­ны оп­ре­де­ля­ют, к ка­ким стро­кам бу­дет при­ме­не­но дей­ст­вие.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
 { split($7, hms, “:”)&lt;br /&gt;
 secs = (hms[1] * 3600) + (hms[2] * 60) + hms[3]&lt;br /&gt;
 printf “%6d %5d\n”, $2, secs&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Про­грам­му мож­но вы­звать та­ким об­ра­зом:&lt;br /&gt;
&lt;br /&gt;
 $ ps -ef | awk -f seconds.awk&lt;br /&gt;
&lt;br /&gt;
Ни один из при­ве­ден­ных при­ме­ров не про­де­мон­ст­ри­ро­вал всей мо­щи ''Awk''. Это пол­но­цен­ный язык со все­ми необ­хо­ди­мы­ми воз­мож­но­стя­ми – пе­ре­мен­ны­ми, мас­си­ва­ми, ариф­ме­ти­кой, цик­ла­ми, ветв­лением и встро­ен­ной биб­лио­те­кой функ­ций. Его на­бор опе­ра­то­ров и син­так­сис его цик­лов и ветв­лений на­по­ми­на­ют ''C'', но без то­чек с за­пя­той.&lt;br /&gt;
&lt;br /&gt;
Что­бы про­де­мон­ст­ри­ро­вать несколь­ко боль­шие его воз­мож­но­сти, на­пи­шем про­грам­му, ко­то­рая об­ра­ба­ты­ва­ет вы­вод коман­ды ''ps'', пе­ча­тая ин­фор­ма­цию об об­щем по­треб­лении па­мя­ти ка­ж­дым поль­зо­ва­те­лем, у ко­то­ро­го есть ак­тив­ные про­цес­сы.&lt;br /&gt;
&lt;br /&gt;
Как все­гда с ''Awk'', пре­ж­де все­го нуж­но ра­зо­брать­ся, как ор­ганизо­ва­ны дан­ные. Вот несколь­ко строк вы­во­да ''ps'':&lt;br /&gt;
&lt;br /&gt;
 $ ps aux&lt;br /&gt;
 USER	 PID	 %CPU	 %MEM	 VSZ	 RSS	 TTY	 STAT START	 TIME	 COMMAND&lt;br /&gt;
 root	 1	 0.0	 0.0	 23820	 2012	 ?	 Ss	12:21	 0:00	 /sbin/init&lt;br /&gt;
 postfix 2012	 0.0	 0.0	 39420	 2224	 ?	 S	12:22	 0:00	 qmgr -l -t fifo -u&lt;br /&gt;
 chris	 2113	 0.0	 0.3	 202092	 13080	 ?	 S	12:23	 0:01	 update-notifier&lt;br /&gt;
 chris	 2182	 0.2	 1.4	 724972	 57568	 ?	 Sl	12:35	 0:20	 evolution&lt;br /&gt;
&lt;br /&gt;
Здесь нас ин­те­ре­су­ет пер­вое по­ле (имя вла­дель­ца) и пя­тое по­ле ('''VSZ'''), по­ка­зы­ваю­щее объ­ем вир­ту­аль­ной па­мя­ти про­цес­са. Идея со­сто­ит в том, что­бы сло­жить все зна­че­ния '''VSZ''' для поль­зо­ва­те­лей chris, root и про­чих, и та­ким об­ра­зом по­лу­чить сум­му для ка­ж­до­го поль­зо­ва­те­ля. Вот на­ша про­грам­ма '''totmem.awk''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
 $1 != “USER” { count[$1]++; tot[$1] += $6 }&lt;br /&gt;
 END {&lt;br /&gt;
 for (user in tot)&lt;br /&gt;
 printf “%8s: %4d %8d\n”, user, count[user], tot[user]&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ее вы­вод вы­гля­дит так:&lt;br /&gt;
&lt;br /&gt;
 $ ps aux | awk -f totmem.awk&lt;br /&gt;
 gdm: 1 26256&lt;br /&gt;
 chris: 60 11502604&lt;br /&gt;
 syslog: 1 126216&lt;br /&gt;
 rtkit: 1 43636&lt;br /&gt;
 daemon: 1 18880&lt;br /&gt;
 postfix: 2 78680&lt;br /&gt;
 nobody: 1 21424&lt;br /&gt;
 avahi: 2 67976&lt;br /&gt;
 root: 113 1769064&lt;br /&gt;
&lt;br /&gt;
Основ­ной эле­мент этой про­грам­мы – два ас­со­циа­тив­ных мас­си­ва '''count''' и '''tot'''. В ка­че­стве ин­дек­са по этим мас­си­вам мы ис­поль­зу­ем имя поль­зо­ва­те­ля (со­хранен­ное в '''$1'''). По­сле об­ра­бот­ки всех строк '''count[«chris»]''' бу­дет со­дер­жать об­щее чис­ло про­цес­сов, вла­де­лец ко­то­рых – поль­зо­ва­тель chris, а '''tot[«chris»]''' – иско­мый объ­ем па­мя­ти. Мас­си­вы '''count[«root»]''' и '''tot[«root»]''' бу­дут со­дер­жать те же дан­ные для поль­зо­ва­те­ля root. Конеч­но, мы не зна­ем за­ранее, ка­кие име­на поль­зо­ва­те­лей по­па­дут­ся, но для цик­ла '''for''' все рав­но, по ка­ким зна­чениям про­хо­дить. Вы­ра­жение '''printf''' очень по­хо­же на вы­зов '''printf()''' – биб­лио­теч­ной функ­ции ''C''. Она по­зво­ля­ет вы­вести дан­ные за­дан­ной ши­ри­ны, и чис­ла ак­ку­рат­но вы­равнива­ют­ся по столб­цам.&lt;br /&gt;
&lt;br /&gt;
===По­счи­тай­те сум­мы===&lt;br /&gt;
&lt;br /&gt;
Остав­лю вас с про­грам­мой немно­го в ином сти­ле – она не счи­ты­ва­ет ника­ких вход­ных дан­ных, а толь­ко вы­пол­ня­ет вы­чис­ления. Она вы­во­дит все про­стые чис­ла, мень­шие 1000. Здесь все де­ло в дей­ствии для шаб­ло­на '''BEGIN'''. Это не са­мый эф­фек­тив­ный ал­го­ритм, и ''Awk'' в лю­бом слу­чае – не луч­ший вы­бор для ра­бо­ты с чис­ла­ми. Но при­мер со­дер­жит несколь­ко цик­лов и ветв­лений и по­ка­зы­ва­ет, как оп­ре­де­лять соб­ствен­ные функ­ции.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
 BEGIN {&lt;br /&gt;
 for (x = 3; x &amp;lt; 1000; x += 2)&lt;br /&gt;
 if (isprime(x)) print x&lt;br /&gt;
 }&lt;br /&gt;
 function isprime(a)&lt;br /&gt;
 {&lt;br /&gt;
 for (n = 2; n*n &amp;lt;= a; n++) {&lt;br /&gt;
 if (a%n == 0)&lt;br /&gt;
 return 0&lt;br /&gt;
 }&lt;br /&gt;
 return 1&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На­де­юсь, вам по­нра­ви­лось мое крат­кое вве­де­ние в ''Awk''. Те­перь оче­редь за ва­ми – ус­пе­хов!&lt;br /&gt;
&lt;br /&gt;
===Где уз­нать боль­ше===&lt;br /&gt;
&lt;br /&gt;
Клас­си­че­ская кни­га «The Awk Programming Language» [Язык про­грам­ми­ро­ва­ния Awk] бы­ла на­пи­са­на соз­да­те­ля­ми язы­ка еще в 1988 го­ду, но все еще из­да­ет­ся. В книге опи­са­на ис­ход­ная вер­сия ''Awk'', но это по-преж­не­му луч­шее ру­ко­во­дство по язы­ку. В ней все­го 200 стра­ниц, но она вы­хо­дит да­ле­ко за рам­ки про­сто­го опи­са­ния язы­ка – с гла­ва­ми о на­пи­са­нии син­так­си­че­ских ана­ли­за­то­ров для «язы­ков-ма­лю­ток» и об ал­го­рит­мах вро­де то­по­ло­ги­че­ской сор­ти­ров­ки. Так­же мож­но за­гру­зить пол­ное ру­ко­во­дство по ''Gawk'' (364 стра­ни­цы) в раз­лич­ных фор­ма­тах с сай­та http://www.gnu.org/software/gawk/manual. Есть еще сайт http://awk.info, где мож­но най­ти ис­чер­пы­ваю­щую под­бор­ку про­грамм на ''Awk'' – от од­но­строч­ных до дей­ст­ви­тель­но серь­ез­ных.&lt;/div&gt;</summary>
		<author><name>Crazy Rebel</name></author>	</entry>

	</feed>