����������� ������������ ��� GNU Awk

Arnold D. Robbins

������� ������� �. �.

5. ������ ������� ������

����������

5.6 ������ ������ ������������� ������

 

(� ���� ������� ����������� �����, ����������������� �����������. ���� �� ��� ��������� ������������ awk, ������ ���������� ��� ��� ������ ������.) � ������ gawk 2.13 ������� ����� �������� ��� �������� � ������ ������������� ������ ��� ������������� ������������ �����. ������ ���� ������� ����������, ��������, �� ����� ������ FORTRAN-��������, ��� ����� ��������� ���� � �����; ��� �� ������ ��������, ������� �� ��������������� �� ������������� � �������� ����� ������ ��������. �������� ��������� ����� ������� �������, ��� ��� ������� ������������ �������������� ����������� ����� �������� � ������ ���� ��������� ���������. ����, ��� �������� � awk ���������� ���������� ����� � ������� FS �������� � ���� ������. ���� ����������� awk-��������� ����� ������������ ������������������ ������� substr ��� $0 (��. ������ 12.3 [���������� ������� ��� �������� �� ��������], ���. 137), ��� ��������� � ������������ ��� ������� ����� �����.

���������� ������� ������ �� ���� ������������� ������ ����������� ����������� ������������ �������, ���������� ����������� ��������� �����, ���������� ���������� FIELDWIDTHS. ������ ����� ��������� ������ ����, ������� ������� ����� ������. ���� ����� ������������ ������� ����� ������, ����� ��������� ������ ��� ��������� ����, ������� ������������ ������������.

��������� ������ ������������ ����� ������� Unix w. ��� ������� ��� ����������� ������������� FIELDWIDTHS.

10:06pm up 21 days,
14:04, 23 users 
User tty login idle JCPU PCPU what
hzuottyV0 8:58pm 9 5 vi p24.tex hzang ttyV3 
6:37pm 50 -csh eklye ttyV5 9:53pm
7 1 em thes.tex dportein ttyV6 8:17pm 
1:47 -csh gierd ttyD3 10:00pm 1 elm
dave ttyD4 9:47pm 4 4 w brent ttyp0 
26Jun91 4:46 26:46 4:41 bash dave ttyq4
26Jun9115days 46 46 wnewmail

��������� ��������� ������ ����������� ���� �����, ��������� ����� ������� (idle time) � ������� � �������� ������ ��� ���� � ����������� ����� �������. (��� ��������� ���������� ��������� ������� awk, ������� ��� �� ���������������.)

BEGIN - FIELDWIDTHS = "9 6 10 6 7 7 35" "" NR ? 2 -
idle = $4 sub(/^ */, "", idle) # strip leading spaces if (idle == "")
idle = 0 if (idle ~ /:/) -
split(idle, t, ":") idle = t[1] * 60 + t[2] "" if (idle ~ /days/)
idle *= 24 * 60 * 60
print $1, $2, idle ""

����� �������� ��������� ���������� ��������� program �� ������:

hzuo ttyV0 0 hzang ttyV3 50 eklye ttyV5 0 
dportein ttyV6 107 gierd ttyD3 1
dave ttyD4 0 brent ttyp0 286 
dave ttyq4 1296000

������ (��������, ����� ����������) ������ ������� ������ ������������� ������ ������������ ���� ������ �������� ��������. � ��������� �������� �Ȱ ���������� ���������� ���� ����� ����������� � �����������. ����� ��� �������� �������������� ��� �������� ������� � ������ ������� ��������� ��� ������-������ ������������� ������������.

��������� ���������� ����� �� ���������� �� ��������� ������������, ����� ������� ����� ����� ���� ������. awk-��������� ��� ��������� ����� ������ ����� ������������ �������� FIELDWIDTHS ��� ��������� ������ ������. (�������, �������� gawk, ������� �������� �� ������� � ������� ���������, ���������� ��������� ������!)

������������ ���������� �������� FS ��������� gawk ��������� � ������������� FS ��� ���������� �����. ����������� `FS = FS' ��� �����, �� ���� �������� �������� FS.

����������� �������� ��� ���������������� � ����� ���� ������������ �� ��������. ������� � ���������, ��� gawk �� �������� ��������� ������������ ��������, ������������ �������� FIELDWIDTHS.

5.7 ������������� ������

 

� ��������� ����� ������ ���� ������ �� ����� ������ ��������� ���������� ����� ������. � ����� ������� ����� ������������ ������������� ������. ������ ����� �� ���� ���� ������ ���� ����� ������� ������: ���� ������ �� ���������� ��� ��������� ������, ��� �� ����������? ��� ������ �� ���������? ���� �� ������������ ������� � ������ ������� ������� ��� ������ ��� �� ����������. ��������, ����� ������������ ������ �������� (������������ ��� `"f' � awk, ���������� ���� ��� � ��), ������������ ������ ������ ��� �������� � �����. ����� ������� ���, ��������� ���������� RS �������� ""f" (�������, ���������� ������ ����� ��������). ����� ����� �������������� ����� ������ ������, �� ���������� ������ ������ � ������.

������ ������� ������� � ������������� ������ ����� ��� ���������� �������. �� ������������ ���������� ������ ������� ��� �������� RS ����� ���������, ��� ������ ����������� ����� ��� ����� ������� ��������. ���� ���������� RS �� ������ �������, ������ ������ ������������ �� ������ ���������� ������ ������. � ��������� ������ �� ����������, ���� �� �������� ������ �������� ������, ��������� �� ����� ����������� ������ �����, ��������������� ��� ����������� �������.

���� �� ������ �������, ��� �� `RS = ""', ����� �������, ���������� RS ������� ""n"n+". ��� regexp ������������� newline � ����� ������ � ����� ��� ����� ������ ����� ����� ������. ����� ����, ������ ���������� ��������� ������ ������������� �������� ������� ��������� ������������������, ����� ������� ����������� ������ (��. ������ 4.6 [����� ������ ������ �������������?], ���. 34). ��� ��� ��������� ������ �� ����������, ���� �� ����� ���������� ������ �������� ������, ����� ������� ���� ������� ������ ������ ����� ������, ��������������� ��� ���� ����������� �������.

������� ������ �������� ����� `RS = ""' � `RS = ""n"n+"'. � ������ ������ ������� ������� newline �� ������� ����� ������ ������������, � ���� ���� ������������ ��� �������������� ������ ����� ����� ��������� ������, �������� newline ��������� �� ������. �� ������ ������ ����� ����������� ��������� �� ������������ (d.c.).

������, ����� ���� �������� �� ������, ��������� ��� ������� � ���������� ����� � ������. ���� ���� ������� � ���������� ������ ������ �� ���� ������� �������. ��� ���������� �� ��������� � ���������� ��������� �����������: ����� RS ��������� ������ ������� string, ������ newline ������ ��������� ��� ����������� �����. ��� ���������� ������������� � ������� ����������� �����, �������������� �� FS. �������� ������� ��� ����� ������������ ���������� ����, ��-��������, ��������� �������� ��������� ��������� � ������ �������� �� ��������� (�.�. ����� FS ����� " "). �� ��� ����� �������� � ���������, ���� �� �� ������, ����� ������ newline �������� ����, ��������� ��� ������� ������������� ����� ��������. �� ����� ������ ��������, ��������� ������� split ��� ����������� ������ ������� (��. ������ 12.3 [���������� ������� ��� �������� �� ��������], ���. 137).

������ ���� ��� ��������� ����� ���� ������������ ����� �� ������ �������: ����� ������� ���, ���������� ��������� ���������� FS ������� ""n". (��� ������� ���������� ��������� ������������� ��������� newline.) ������������ �������� ����� ������, ��������������� ����� �������, ����� ���� ������ �������, ��� ����� ������ ��������� ������� ��������. ���� ������ ������� ��������� � ����� � ������ `addresses', �� �������� �������� ���:

Jane Doe 123 Main Street Anywhere, SE 12345-6789
John Smith 456 Tree-lined Avenue Smallville, MW 98765-4321
...


������� ��������� ��������� ������ 
����� ����� ������� ���������:

# addrs.awk --- ������� ��������� ��� ������ �������
# ������ ��������� ������� ��������.
# ������ ������ ������� �� ������ ����.
BEGIN - RS = "" ; FS = ""n" ""
-
print "Name is:", $1 print "Address is:", 
$2 print "City and State are:",
$3 print "" ""

���������� ��������� ������� ��������� �����:


$ awk -f addrs.awk addresses
a Name is: Jane Doe
a Address is: 123 Main Street
a City and State are: Anywhere, SE 12345-6789
a
a Name is: John Smith
a Address is: 456 Tree-lined Avenue
a City and State are: Smallville, MW 98765-4321
a...

��. ������ 16.2.4 [������ �������� �����], ���. 233, ��� ������� ����� ���������� ��������� � ��������� ��������. ��������� ������� �������� ������� �������� � ���������� ������� � ������� �������� RS. (`==' �������� "����� ��������")

RS == ""n" ������ ��������� ��������� newline (`"n'). � ����������������, ������ ������ � ����� ������ ���� ��������� ������, ���������� ������ ������. ��� --- �������� �� ���������.

RS == ����� ��������� ������ ������ ����������� ����������� ����� �������. ������� ���������������� ��������� ������������ ������ ������.

RS == "" ������ ����������� �������� ������ �����. ������ newline ������ �������� ����������� �����, � ���������� � ������ �������� � FS. ������� � �������������� newline � ����� ������������.

RS == regexp ������ ����������� ����������� ��������, ��������������� regexp. ������� � �������������� ������������ regexp ������������ ������ ������.

�� ���� ������� gawk ����������� RT ������� �����, ��������������� ��������, ���������� � RS.

5.8 ����� ���� �� ������� getline

 

�� ��� ��� �� �������� ���� ������� ������ �� �������� �������� ������ awk, �.�. ��� �� ������������ ���������� ����� (������ ��� ��������, ������ �� ������ ������ ���������), ��� �� ������, ��������� � ��������� ������. ���� awk ����� ����������� ���������� �������, ���������� getline, ������� ����� ������������ ��� ������ ����� ��� ����� ��������� ������������.

5.8.1 �������� ��� getline

 

��� ������� ������������ ����������� ���������� ��������� � �� ������������� ��� ����������. ��� ����������� ����� ������, ��� ��� ��������� ����� ��������� �����. �������, ������� ������� �� ������������ �������� getline, �������� ��������, ������� ��� �� ����������. ������� �� ����������� ��� ��������� ����� ��� �������� ������� getline ����� ����, ��� �� ������������� � ��������� ������ ����� � ����������� ������� ������ ����, ��� �������� awk.

getline ���������� ��� 1, ���� ����� ������, � ��� 0 ���� ���������� ����� �����. ���� ��� ������ ������ ����������, ��� ���� ������ �������, �� getline ������ \Gamma 1. � ����� ������ gawk ������������� � ���������� ERRNO ������� � ��������� ����������� ������. � ����������� �������� ����� command �������� �������� �������, �������������� ������� ��������.

5.8.2 ������������� getline ��� ����������

 

������� getline ��� ���������� ����� �������������� ��� ������ �� �������� �������� �����. ���, ��� ��� ������ � ���� ������, ������� � ������ ��������� ������� ������ � ����������� �� �� ����. ��� �������, ���� �� ��������� ��������� ������� ������ � ������ ����������� ��������� ������ �����-�� ����������� ���������.

���������� ������:

awk '-
if ((t = index($0, "/*")) != 0) -
# value will be "" if t is 1 tmp = substr($0, 1, t - 1) u = index
(substr($0, t + 2), "*/") while (u == 0) -
if (getline != 0) -
m = "unexpected EOF or error" m = (m ": " ERRNO) print m ? "/dev/stderr"
 exit "" t = -1 u = index($0, "*/") "" # substr expression will be "" if */
# occurred at end of line $0 = tmp substr($0, t + u + 3) "" print $0 ""'

��� awk-��������� ������� ��� ����������� C�-����, `/* ... */', �� �����. ����������� ������ `print $0' ������� ����������� �� ������ ����������� ����� ������� ��������� ����� � ���������� �������������, ����� ��� ����� ������������ ����������� ���������. ��� ��������� ����� ���� ���������� --- ��� �� ��������, ���� ���� ����������� ���������, � ������ ���������� �� ��� �� ������.

��� ����� ������� getline ������������� NF (���������� �����; ��. ������ 5.2 [������������ �����], ���. 40), NR (���������� ����������� ���� �������; ��. ������ 5.1 [��� ���� ����������� �� ������, ���. 37), FNR (���������� �������, ����������� � �������� �����) � �������� $0.

���������: ����� �������� $0 ������������ ��� �������� �������� ����� ����������� ������. �������� �������� $0, ������� ������� ������� � ����������� getline, ��������� (d.c.). � ������� �� �����, ��������� �������� ������ ����� ������ � ���������� �������� �� ��������� ���������� �������, ������� � ������� ������� � ���������. ��. ������ 9.7 [��������� ��������], ���.111.

5.8.3 ������������� getline � ����������

 

����� ��������������� `getline var' ��� ������ ��������� ������ �� ����� awk � ����������. ������� ������ ��������� ��� ���� �� ����������. ��������, �����������, ��� ��������� ������ ���� ����������� ��� ��������� ����������� ������� � �� ������ �������� �� ��� ������������ �����-������ ������. ��� ����� getline ��������� ��� �������� ��� ������ � ��������� �� � ���������� ��� ��� ������� ���� ������-������-�-���������-������-������� �� ������� �� ���������.

��������� ������ ������������ ������ ���� ����� � �����. 

����� ������:

wan tew free phore

����� �� ������:

tew wan phore free

��� ��� ���������:

awk '-
if ((getline tmp) ? 0) -
print tmp print $0 "" else
print $0 ""'

����� ����� getline ������������� ������ ���������� NR and FNR (�, �������, var). ������ �� ����������� �� ����, ��� ��� �������� ����� (������� $0) � �������� NF �� ��������.

5.8.4 ������������ getline �� �����

 

`getline ! file' ������������ ��� ������ ��������� ������ �� ����� file. ����� file ���� ��������� �� ��������� �������, ����������� ��� �����. `! file' ���������� ����������������, ��������� ���� ���������� ���� �� ������ ��������. ��������, ��������� ��������� ������ ���� ������� ������ �� ����� `secondary.input' ����� ����������� ������� ���� �� ���������, ������ 10 � ������� ������� �����.

awk '-
if ($1 == 10) -
getline ! "secondary.input" print "" else
print ""'

��������� ������� ������� ����� �� ������������, �������� NR � FNR �� ��������. �� ���������� ������ ����������� �� ���� ���������� �������, ��� ��� �������� $0 � ������ ����� ����������. � ����� �������� NF.

� ������������ � POSIX, `getline ! expression' �� ����������, ���� expression �������� ��������� ��� ������, �������� �� `$'; �������� , `getline ! dir "/" file' �� ����������, ��������� �������� ������������ �� �������� � ������. ����� ������ `getline ! (dir "/" file)', ���� �� ������, ����� ���� ��������� ���� ����������� �� ������ ���������� awk.

5.8.5 ������������� getline � ���������� �� �����

 

������� `getline var ! file' ������������ ��� ������ ����� �� ����� file � ��������� ��� � ���������� var. ��� � ����, file �������� ��������� �� ��������� �������, ������� ���������� ���� ��� ������. � ���� �������� getline �� ���� �� ���������� ���������� �� �������� � ������ �� ����������� �� ����. ���������� ������ ���������� var.

��������, ��������� ��������� �������� ��� ������� ����� �� �����, �� ����������� ������� ����: `@include filename'. ������ ����� ������ ���������� ���������� ����� filename.

awk '-
if (NF == 2 && $1 == "@include") -
while ((getline line ! $2) ? 0)
print line close($2) "" else
print ""'

�������, ��� ����� ��� ��������������� �������� ����� �� �������� � ���������; ��� ������� �� ������, a �� ������� ���� � ������ `@include'. ������� close ���������� ��� ����������� ����, ��� ���� ��� ���������� ������ `@include' �������� �� �����, �� ���� ��������� ���� ����� ������� ������. ��. ������ 6.8 [�������� ������� � �������� ������ � ���������], ���. 74.

���������� ���� ��������� � ���, ��� ��� �� ������������ ��������� `@include' (��������� `@include' � ���������� ������) ���, ��� ��� ������ �����-������������. ��. ������ 16.2.9 [������� ������ ������������� ������������ �������], ���. 244, � ����������, ������� ������������ ��������� ��������� `@include'.

5.8.6 ������������� getline �� ���������

 

����� ���������� ���������� (pipe) ����� �� command � getline, ��������� `command -- getline'. � ����� ������ ����� command ����������� ��� ������� �������� � �� ����� ���������� � awk ��� ������������� � �������� �����. ��� ����� getline ������ �� ��� ���� ������ �� ���������.

��������, ��������� ��������� �������� �� ���� �� �����, �� ����������� �����, ������� ���������� � `@execute'; ����� ������ ���������� �������, ���������� ��� ���������� ������� ������ � �������� ������� ��������.

awk '-
if ($1 == "@execute") -
tmp = substr($0, 10) while ((tmp -- getline) ? 0)
print close(tmp) "" else
print ""'

������� close ���������� ��� ����, ����� � ������ ���� ���������� ����� `@execute' �� ����� ������� command ����������� ��� ������ �� ���. ��. ������ 6.8 [�������� ������� � �������� ������ � ���������], ���. 74.

����� ����� ����:

foo bar baz @execute who bletch

��������� ����� ������:

foo bar baz arnold ttyv0 
Jul 13 14:22 miriam ttyp0 
Jul 13 14:23 (murphy:0)
bill ttyp1 
Jul 13 14:23 (murphy:0) bletch

�������, ��� ��� ��������� ��������� ������� who � �������� ���������. (���� �� ���� ��������� ��� ���������, �� ��������, �������, ������ ���������, ������������ ���, ��� ������ �������� �� ����� �������.)

���� ������� getline ��������� ������ �� ����, ������������� �������� NF � ���� ��������� �������� $0. �������� NR � FNR �� ��������. � ������������ � POSIX, `expression -- getline' �� ����������, ���� expression �������� �� ����������� � ������ ���������, �������� �� `$'; ��������, `"echo " "date" -- getline' �� ����������, ��� ��� ������������ �� ��������� � ������, ����� ������ `("echo " "date") -- getline', ����� ��������� ���� ����������� �� ������ ���������� awks. (������, ��� gawk �� �������� ���������, �� �� ��� �� ���� ����������. �� ������ ������, ������ ������ ��������� ����� ��������.)

5.8.7 ������������� getline � ���������� �� ���������

 

���� �� ���������� `command -- getline var', ����� ������� command ����� ������ �� ��������� � getline � � ���������� var. ��������, ��������� ��������� ������ ������� ���� � ����� � ���������� current.time, ��������� ������� date, � ����� �������� �������� ����������.

awk 'BEGIN -
"date" -- getline current.time close("date") 
print "Report printed on "
current.time ""'

� ���� ������ getline �� �������� �� ���� �� ���������� ���������� � ������ �� ����������� �� ����.

5.8.8 ������ ��������� getline

 

��� ���� ���� getline, ���� ���� $0 � NF �����������, ������ �� ����������� �� ��������� � ���� �������� � awk-���������, ���, ��� ��� ���� �� � ������ ������ ������ ���������, � ������� ����� ��������� awk. ������, ����� ������ ����������� �� ������� ������������ �������.

������ ���������� awk ������������ ���������� ����������, ������� ����� ������� awk-���������, ������ �����! � gawk ������ ����������� ���. ���� ������� ������� ����������, ������� ��������� ������������ �������.

���������� �������� ������ ����� ���������, ���� �� ����������� getline (��� ���������������) ������ ������� BEGIN. ��������� �� ���������������� getline ������ �� ������ ������ ��������� ������, ������ ������� getline ���������� awk ���������� �������� � FILENAME. ��������� FILENAME �� ����� �������� ������ ������ BEGIN, ��������� ��� �� �������� ��������� ������ � �������, ��������� � ��������� ������ (d.c.). (��. ������ 8.1.5 [����������� ������� BEGIN � END], ���. 100, � ������ 10.2 [���������� ����������, ������� �������� ����������], ���. 117.)

��������� ������� �������� ���� ����� ��������� getline � ����������� ���������� ����������, ������� ��������������� � ������ �� ���������.

getline �������������  $0, NF, FNR and NR.
getline var �������������  var, FNR and NR.
getline ! file �������������  $0 and NF.
getline var ! file ������������� var.
command -- getline ������������  $0 � and NF.
command -- getline var �������������  var.