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

Arnold D. Robbins

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

����������

16. ������������ awk-���������

16.2 ������ awk-���������

 

���� ������ �������� ����� ������ ��������. �������� , ��� �� ������� �� � ����������� � ���������.


1 ���������� ��� �� ������� 15.9 [�������� �� ��������� ������ � �������], ���. 185. ������ wc ���������� ��������� ���������� lines ������ �������� FNR � endfile?


16.2.1 ���������� ��������� ���� � ����������

 

������� ������� ��� ��������� ������� ������� ������������� ������ �������� ��������� ���������� ����. �� ����� ������ ������� � ������ ���-������ �������� ������: "the the program does the following . . . ." ����� ����� ���������� �� ������, ����� ������������� ����� ���������� � ����� ����� ������ � ������ ���������, ����� �� ������ ���������������. ������������ ���������, `dupword.awk', ������������� ���� �� ����� ������ �� ��� � ���� �������� ��������� ���������� ����. ��� ����� ���������� ��������� ����� ������ (� ���������� prev) ��� ��������� � ������ ������ � ��������� ������. ������ ��� ��������� ������������ ��� ����� ������ �������, ��� ���, ��������, "The" � "the" ��������� ������� ���� �����. ������ �������� ������� ��� �����������, ���������� � ��-whitespace ������� �� ������, ��� ��� ���������� �� ������ �� ���������. ��� ������ �������� � �������� ������� ����, ������� �� ����� ���� ��������, �� ����� ������ �����.

# dupword --- ������� ��������� ����� � ������
# Arnold Robbins, arnold@gnu.org, Public Domain # December 1991
-
$0 = tolower($0) gsub(/[^A-Za-z0-9 "t]/, ""); if ($1 == prev)
printf("%s:%d: duplicate %s"n",
FILENAME, FNR, $1) for (i = 2; i != NF; i++)
if ($i == $(i-1))
printf("%s:%d: duplicate %s"n",
FILENAME, FNR, $i) prev = $NF ""

16.2.2 ���������-���������

 

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

��� ��������� ���������� ������� gettimeofday �� ������� 15.8 [���������� ��������], ���. 183.

��� ������ ������������� � ������� BEGIN. ������ ����� ���� �������� ���������� � ��������� �� ���������: ���������� ��� ����������, ���������� ����������, ��������� ��� ������. ���� ������������ ����� ���������, �� ��� �� �������� ASCII BEL ������� (����������� �������� "��������!") `"a'), �� �� ����������� � ���������. (�� ������ �������� ������ ASCII BEL ���������� �������� ������. ����� �������, ����� ��������� ���������, ������� ���������� � ���� ��������, �� ������, ���� ������������ �� ������� �� ��������� ��� ��������.)

# alarm --- ���������� ���������
#Arnold Robbins, arnold@gnu.org, Public Domain # May 1993
# ������������: alarm time [ "message" [ count [ delay ] ] ]
BEGIN " -
# �������� ������������ ����������
usage1 = "usage: alarm time ['message' [count [delay]]]"
usage2 = sprintf(""t(%s) time ::= hh:mm", ARGV[1])
if (ARGC ! 2) -
print usage ? "/dev/stderr" exit 1 "" else if (ARGC == 5) -
delay = ARGV[4] + 0 count = ARGV[3] + 0 message = ARGV[2] "" else
if (ARGC == 4) -
count = ARGV[3] + 0 message = ARGV[2] "" else if (ARGC == 3) -
message = ARGV[2] "" else if (ARGV[1] !~ /[0-9]?[0-9]:[0-9][0-9]/) -
print usage1 ? "/dev/stderr" print usage2 ? "/dev/stderr" exit 1 ""
# ��������� �� ���������
if (delay == 0)
delay = 180 # 3 ������
if (count == 0)
count = 5
if (message == "")
message = sprintf(""aIt is now %s!"a", ARGV[1]) else
if (index(message, ""a") == 0)
message = ""a" message ""a"

��������� ����� ���� ���������� time � ���� � ������, � ���� ��� �����, � 24-������� �����. ����� ��� ������������ � ���������� ������ ����� ��������. ����� ������� ����� ����������� � ���������� ������ � ��������. �������� ����� ���� ����������, ��� ����� ����� �� ��������� ����������.

# ����������� ������������ �������
split(ARGV[1], atime, ":") hour = atime[1] + 0 # �����. � �����
minute = atime[2] + 0 # �����. � �����
# ��������� �������� ������������� �������
gettimeofday(now)
# ���� ����� ������ �� 12-������� �����  � ��������� �������,
# ��������, `alarm 5:30' �  9 a.m. ������  5:30 p.m.,
# �� �������� 12 � ��������� ����
if (hour ! 12 && now["hour"] ? hour)
hour += 12
# ���������� ����������� ����� target � �������� � ��������
target = (hour * 60 * 60) + (minute * 60)
# �������� ������� ����� � �������� � ��������
current = (now["hour"] * 60 * 60) + "
(now["minute"] * 60) + now["second"]
# ��� ����� ����� �������
naptime = target - current if (naptime != 0) -
print "time is in the past!" ? "/dev/stderr" exit 1 ""

�������, ��������� ���������� ��������� ������� (��. ������ 12.4 [���������� ������� �����/������], ���. 146) ������ ������� sleep. ��� ������� ������ ���� ��������� ���������� ������. ���� ������������ ��������� �� 0, ��������� �������, ��� sleep ���� ��� ��������, � ���������� ������. ���� sleep ���������� ��������� 0, �� ��������� �������� � ����� ��������� � ����� ���������� sleep ��� �������� ���������� ������� ����� ������ ���������� ������.

# zzzzzz..... go away if interrupted 
if (system(sprintf("sleep %d", naptime)) != 0)
# zzzzzzzzzzzzzz ...... ����� �� ����������
if (system(sprintf("sleep %d", naptime)) != 0) exit 1
# ����� ��� ���������!
command = sprintf("sleep %d", delay) for (i = 1; i != count; i++) -
print message # ���� ������� sleep ��������, �� �����
if (system(command) != 0)
break ""
exit 0 ""

16.2.3 �������������� ��������

 

��������� ������� tr ���������� �������������� ��������. ��������, ��� ����� ������������ ��� �������� ���� �������� �������� � ��������������� ������ � ����� ���������� ���������: �������������� ������ -- tr '[A-Z]' '[a-z]' -- ��������� ������ ...

������� tr ������ ��� ������ ��������, ����������� � ���������� ������. ������ ������ ������� � �������, ����� �������� �������� �� ������� ���������� �������� ����. *2* ��� ��������� ����� ������ ������ �� ������� ������ ���������� ������ �������� �� ������ ������, ������ ������ �� ������� ������ ���������� ������ �������� �� ������ ������, � �.�. ���� � ������ "��" �������� ������ ��� � ������ "�", �� ��������� ������ � ������ "�" ������������ ��� ���������� �������� ������ "��".

��������� ����� ����� ���� �� ������������� ��������� ��� �������� � gawk ��� �������. ������ ����������� "��������� ���������", � ������� ��������� ���������, ����� ��������, ��� �������������� ����� �������������� �� ������ ���������������� �������. ��� ��������� �� ��� �����, ��� ��������� ������� tr, �� ��� ����� ��������� ����������� ������.

��������� ���������� ������������� ���� �� �������� ��������� ����������� awk: �������� � ���������� ��������� ����� ����������, ������ ���������� ������������ ���������� ������� substr, index � gsub (��. ������ 12.3 [���������� ������� ��� �������� � ���������], ���. 137).*3*


2 �� ������, ��-POSIX, �������� tr ����� �� �������, ����� ������ ����������� � ���������� ������ � �������.


3 ��� ��������� ���� �������� �� ����, ��� gawk �������� ����������� �������� ������ ������ ������� � ��������� ������� �������. ��� � ������� ����� �������� ����� ��������� ���������?


������� ��� �������. ������ �� ���, stranslate, ����� ��� ���������. ������ from A �������� �������, ���������� ����������. ������ to A �������� �� ������ ����� ����������. target ������������ �������, ���������� ����������.

������������� ������� ������ ���������� ���������� �������. t.ar �������� ������� "�", ��������������� ��������� "��". ������� ���� ���������� ������� "��". ��� ������� ������� � "��", ���� �� ���������� � target, ������������ ������� gsub ��� ��� ������ �� ��������������� ������.

������� translate ������ �������� stranslate, ��������� $0 ��� target. ������� ��������� ������������� ��� ���������� ����������, FROM � TO, �� ��������� ������ � ����� �������� ARGV ���, ��� awk ����� ������ �� ������������ �����. �������, �������������� ������� ������ �������� translate ��� ������ ������.

# translate --- ��������� �������  tr
# Arnold Robbins, arnold@gnu.org, Public Domain # August 1989
# ��������: �� �������� ����� ��� , ���  tr A-Z a-z,
# �� ���� `to' ������ ���  `from',
# ��������� ������ �  `to' ������������ ��� ������� �  `from'.
function stranslate(from, to, target, lf, lt, t.ar, i, c) -
lf = length(from) lt = length(to) for (i = 1; i != lt; i++)
t.ar[substr(from, i, 1)] = substr(to, i, 1) if (lt ! lf)
for (; i != lf; i++)
t.ar[substr(from, i, 1)] = substr(to, lt, 1) for (i = 1; i != lf; i++) -
c = substr(from, i, 1) if (index(target, c) ? 0)
gsub(c, t.ar[c], target) "" return target ""
function translate(from, to) -
return $0 = stranslate(from, to, $0) ""
# ������� ���������
BEGIN -
if (ARGC ! 3) -
print "usage: translate from to" ? "/dev/stderr" exit ""
FROM = ARGV[1] TO = ARGV[2] ARGC = 2 ARGV[1] = "-" ""
-
translate(FROM, TO) print ""

���� � �������� ����������� �������������� ���������� ���������������� �������, ��� ������������ ����������, � �� ������������� ������ � ���������� ���������� �������. ������ ������ ����� ��������� ���� ��������� �� ������, ��� System V Release 4 awk ������� ������� toupper � tolower. ��� ������� ������������ ����������� �������, ��� ���������� ��������������, ��� ��� �� ������ ������ �������� ��� ������� � gawk � �� ���� ������������.

���� ��������� ������������������ ����������� ��������� ����� ���� � ��������� ������� t.ar ������ ���� ���, � ������� BEGIN. ������, ��� ������������, ��� ������ "��" � "�" �� ����� �������� �� ����� ������ ���������.

16.2.4 ������ �������� �������

 

��� ��������� �� "��������� ����". *4* ��� ������ ������ ���� � ������� � ���������� �������� ������. ������ �������� ������� �������� 20 �������, ��� ������� � ������ ������ ����. ������ �������������� �� ��������� ���� ����� � �������. ������ ����� ���������� �� ���������� ������� ��������.


4 "�������� ���" ������������ ��� " ��������� ������������� ������������ ��� ������-�� ����."


�������� ���� ������� � ������ ������ ��� 20 �������. ������ ������ ������� ������ ������������ � ������� �����. ������������ ������� ������������� ��� ���������� ������� ����� � ������ �������� ����� ����, ��� ����� ��������� 20 �������.

������� BEGIN ������ ������������� � RS ������ �������, ��� ��� awk ����� ��������� ������ �������� �������� (��. ������ 5.1 [��� ���� ����������� �� ������], ���. 37). ��� ������������� MAXLINES �� 100, ��������� MAXLINE ���� ���������� ����� �� �������� (20 * 5 = 100).

����������� ������ ������ ������� printpage. ������ ������ ������������ ��������������� � ������� �����. �� ��� ������ ���������� �������������; ������ line[1] ����� �� line[6], line[2] ����� �� line[7], � �.�. ��� ����� ������������ ��� ���� ��������. ������� ���� � ���������� i ����� ��� � 10 ����� ������; ��� ���� ���� ��� �������. ���������� ���� � ���������� j ��������� ������ � �������� ����. ��� ��� j �������� �� 0 �� 4, `i+j' ���� j-� ������ � ���� � `i+j+5' ���� ���� � ��������� ���. ����� ������������� ������� ����������:

line 1 line 6 line 2 line 7 line 3 line 8 line 4 line 9 line 5 line 10

� ����������, �� ������� 21 � 61, ���������� �������������� ������ ������, ����� ����� ������������ �� �������. ��� ������� �� ������������ ������������ ������� � �� �����, ����� �������� ���������. �� ����� �������, ��� ������� ��� ������ ������ ������� � �����.

������� END �������� ���, ��� ��������� ��������� �������� � ��������; ���������� ������ ����� ���� �� ������ 20 �������.

# labels.awk
# Arnold Robbins, arnold@gnu.org, Public Domain # June 1992
# ��������� ������ ������� �� 5 ����� ������,
# �������� ������ ������ . �������� ������� ����� �� 2
# ������ ������ ������ � �����.
BEGIN - RS = "" ; MAXLINES = 100 "" function printpage( i, j) -
if (Nlines != 0)
return
printf ""n"n" # header
for (i = 1; i != Nlines; i += 10) -
if (i == 21 ---- i == 61)
print "" for (j = 0; j ! 5; j++) -
if (i + j ? MAXLINES)
break printf " %-41s %s"n", line[i+j], line[i+j+5] "" print "" ""
printf ""n"n" # footer for (i in line)
line[i] = "" ""
# ������� ������� -
if (Count ?= 20) -
printpage() Count = 0 Nlines = 0 "" n = split($0, a, ""n")
for (i = 1; i != n; i++)
line[++Nlines] = a[i] for (; i != 5; i++)
line[++Nlines] = "" Count++ ""
END " -
printpage() ""

16.2.5 ������������� ��������� ������������ ����

 

��������� ���� awk-��������� �������� ���������� ��������� ������� ����� � �����. ��� ������������ ������������� ������� �������� � awk ����������� ������������ ������� � �������� ��������. ��� ����� ������������� ����������� `for x in array'.

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

awk ' # ���������� ������ ������� ������������ ���� -
for (i = 1; i != NF; i++)
freq[$i]++ ""
END -
for (word in freq)
printf "%s"t%d"n", word, freq[word] ""'

������, ��� ����� �������� �� ���� ���������, ��� ��, ��� ��� ����� ��� �������. ������ �������, ������� ������ �������, ����������� ��� ������ ������ �� �����. ��� ���������� �������� awk ��� ������� � ����� (��. ������ 5.2 [������������ �����], ���. 40) ��� ������� ��������� ���� �� ������ � ���������� ���������� NF (��. ����� 10 [���������� ����������], ���. 115) ��� ����������� ����� �����.

��� ������� �������� ����� ���� �� ��������� ������� freq ������������� �� 1 � ���� ����, ��� ����� ��������� ��� ���.

������ �������, ��� ��� ��� ����� ������� END, �� ����������� ���� �� ��������� ����. ��� �������� ���������� ������� freq, ������� ���� ��������� �� ������� �������.

��� ��������� ����� ��������� �����������, ������� �� ��������� �� ���� �������� � ������ �������� ��������� ������:

����� ������������ � �������������� ���������� awk, ��� ���� ���������� ����������� whitespace � ��� ������ ������� � ����� (����� newline) �� ����� ������������ ������ ��� ������, ��� ���������� ��������� ������ ����.

���� awk ������������� ������� �������� � ������� ��������� ��� ���������. �������������, `bartender' � `Bartender' �� ��������������� ��� ���� � �� �� �����. ��� ������������, ��������� � ���������� ������ ����� ���������� � ������� �����, ���� ����� � ������ �����������, � ���������� ������� �� ������ ��������� ��.

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

���� ��� ������� ���� ������� ������� � ������������� ����� ����������� ������� ����� awk. ������ �����, ����� ������������ tolower ��� ���������� �������� � ���������. �����, ������������ gsub ��� �������� ������ ����������. �������, ����� ������������ ��������� ������� sort ��� ��������� ������ �� �������� awk. ��� ����� ������ ���� ���������:

# �������� ������ ������ ���� -

$0 = tolower($0) # ��������� �������� � ���������
gsub(/[^a-z0-9. "t]/, "", $0) # ��������� ����������
for (i = 1; i != NF; i++)
freq[$i]++ ""
END -
for (word in freq)
printf "%s"t%d"n", word, freq[word] ""

�����������, ��� ��� ��������� ����� � ����� � ������ `wordfreq.awk' � ��� ������ ����� � ����� `file1'. ����� ��������� ��������

awk -f wordfreq.awk file1 -- sort +1 -nr

������ ������� ����, ������������ � ����� `file1' � ������� �������� �������.

��������� awk ������������� ������ � ������ ��������������� ������� ����. ����� ��������� awk ����������� �������� sort � ���������� �� ���������. ��������, ��������� ��� sort � ����� ������, ������������ ���������� �� ������� ���� ������� ����� (��������� ���� ����), ��� ��� ����� ���������� ������ ��������������� ��� ����� (����� `15' ����� ���� �� `5'), � ��� ���������� ������ ���� � ���������� (��������) �������. �� ����� �� ���� ������� ���������� ������ ���������, ������� �������� END ���:

END -
sort = "sort +1 -nr" for (word in freq)
printf "%s"t%d"n", word, freq[word] -- sort close(sort) ""

����� ��������� ���� ������ ���������� �� ��������, ������� �� ����� ��������� ����������.

��. ����� ������������ �� ������������ ������� � ������� ������������� ��������� sort.

16.2.6 �������� ���������� �� ���������������� ������

 

��������� uniq (��. ������ 16.1.6 [������ ��������������� ����� ������ ], ���. 220), ������� ������������� ������ �� ���������������� ������. �����������, ��� ����� ������� ������������� ������ �� ����� � �������, �� � ����������� ������������� ������� �����? ������� �������� ����� ����� ���� ���� ������� ��������. �� �������� ����� ���� �������� ������ � ���������, ��� �� �� ������� ����������� ��������� ���. ��������, �� �������� ����� ������� ��������� ������������� ������. �� ���������� ��������� ������� ������������ ������.

��������� ������� ��������� ������ ������. ��� ���������� ��� �������. ������ data ������������� �������� ������ ������. ��� ������ ������ data[$0] �������������. ���� ��������� ������ �� ���������� ������, �� data[$0] ����� ����� . � � ���� ������ ����� ������ ������������ � lines[count]. ������ ������� � lines ���� ���������� �������, � ������� � lines ��������� �������, � ������� ��� ������ ���� ����������. ������� END ������ ������������� ������ lines � ������� count

# histsort.awk --- ������ ������� ��������
# Arnold Robbins, arnold@gnu.org, Public Domain # May 1993
# ���������  Byron Rakitzis �� ����� ���� -
if (data[$0]++ == 0)
lines[++count] = $0 ""
END -
for (i = 1; i != count; i++)
print lines[i] ""

��� ��������� ����� ������������ ��������� ��� ��������� ������ �������� ����������. ��������, ��������� ��������� �������� ������ � ������� END, ����� ���������, ��� ����� ��������� ������� ���� ������������:

print data[lines[i]], lines[i]

��� ��������, ��� ��� data[$0] ������������� ������ ���, ����� ���������� ������.

16.2.7 ���������� �������� �� ������ Texinfo Source

 

� ��������� ����� � ���������� ����� 15 [���������� awk-�������], ���. 169), �������� ������� ���������� awk-��������. ���� �� ������ �������������������� � ����� �����������, ����� ������ �������������� �� �������. �� ���������� ���������, ������� ����� ��������� ����� Texinfo input file � ��������� �����.

��� ����� �������� �� Texinfo, ����� GNU ��� �������������� ��������� ������������. ������ Texinfo source file ����� ���� ����������� ��� ��������� � �������� � ���������� ������������. Texinfo ��������� �������������� � Texinfo-- GNU Documentation Format, � �������� �� Free Software Foundation.

��� ����� ����� ���������� ����� ��� ���� �� Texinfo input files.

The "at" ������, `@', �������� �����������, �� ������ �������� `"' � �� ��� awk. ���������� ������� `@' ������������ � Texinfo source files ��� `@@'.

����������� ���������� � ��� `@c' ��� `@comment'. ��������� ���������� ������ ����� �������� ��� ������������� ����������� ������������, ������� ���������� � ������ ������.

����� �������, ������� �� ������ ����������� �� �������� �������, ����������� ����� ��������, ����������� ������� `@group' `@end group'.

��������� ���������, `extract.awk', ������ Texinfo source file � ������ ��� ���� �� ��������� ����������� ������������. ��������� `@c system ...', ��� ��������� �������, �������� ����� ������� �� ��������� ������ � ��������� ��� ��������� ������� (��. ������ 12.4 [���������� ������� ��� �����/������, ���. 146). �� ����������� `@c file filename', ������ ����������� ������ ����� ���������� � ���� filename, ���� �� �������� `@c endfile'. ������� � `extract.awk' ����� ��������������� ���� `@c' ���� `@c comment', �������� ���������������� ����� `omment'. ������, ���������� `@group' � `@end group' ������ ���������. `extract.awk' ���������� ������������ ������� join (��. ������ 15.6 [����������� ������� � �������], ���. 176).

����������� ������� � ���������� Texinfo source ��� ������������ AWK-���������������� (`gawk.texi') ������ ���� ��� ��������� ����� �������� `file' � `endfile'. �������������� gawk ���������� ����� `extract.awk' ��� ���������� �������� �������� � ��������� ������ �� ��� � ����������� ��������, ��� gawk ����� �� �����. ���� Texinfo �������� ������ ������� ����������:

...

��� ��������� ����� ���� @code-BEGIN"" , 
������� �������� �������� ���������:

@example @c file examples/messages.awk
BEGIN @- print "�� ���������!" @"" @c end file @end example

��� ����� �������� �������������� �����:
@example @c file examples/messages.awk END @-
print "������ ��������� ������� ����������!" 
@"" @c end file @end example ...

`extract.awk' �������� � ��������� IGNORECASE �� ����, ��� ��� ����� �������� � ������� ��������� � ���������� �� ����� ����� ��������.

������ ������� ���������, ������� �������, ��������, ��� ������� ���� ������ (NF ����� �� ������� ���� ����), � ����� ���������, ��� ������� ��������� ������ � ���������� 0, ���������� OK.

# extract.awk --- ������� ����� � ��������� ���������
# �� texinfo files 
# Arnold Robbins, arnold@gnu.org, Public Domain 
# May 1993

BEGIN - IGNORECASE = 1 "" /^@c(omment)?[ "t]+system/ " -
if (NF ! 3) -
e = (FILENAME ":" FNR) e = (e ": badly formed `system' line")
print e ? "/dev/stderr" next "" $1 = "" $2 = "" stat = system($0)
if (stat != 0) -
e = (FILENAME ":" FNR) e = (e ": warning: system returned " stat)
print e ? "/dev/stderr" "" ""

������������ ���������� e, ��� ��� ������� ������ ����������� � ��������. ������ ������� ��������� ��������� ������ � �����. ��� ���������, ��� ��� ����� ���� ������� � ���������. ���� ��������� ���� �� �������� �������, �� ������� ���� �����������. ��� ������, ��� ��������� `@c endfile' �� ��� ����� ��� ����� �����.

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

���� `for' ��������� ���� ������. �� ������ ������ � ������� getline (��. ������ 5.8 [����� ���� �� getline], ���. 53). ��� ����������� ����� ����� ��� �������� ������� unexpected.eof. ���� ������ ���� "endfile" , �� ��� ��������� ����. ���� ������ ���� `@group' ��� `@end group', �� ��� ���������� �� � ��������� � ��������� ������. (��������� ������ Texinfo control ������ ����� ���� ������ �� ����� ��������; � ���������, TEX �� ������ ���������� �����, ����� ������ ��� ���������, � �� ������ ������ ��� ������.)

������� ����� ������ ������������� ����������� ���������� ��������. ���� � ������ ��� �������� `@', ��� ����� ���� ��������������� ����������. � ��������� ������ ������ ������� `@' ������ ���� �����.

��� �������� �������� `@' ������ ������ ���� ���������� �� ��������� �������� ������� a � ������� ������� split (��. ������ 12.3 [���������� �������], ���. 137). ������ ������� ������� a, ������� ����, ��������� �� ��� �������� ������� `@' � ������������ ������. ��� ������ ���� ������ ��������� (`@@' � ������������ �����), �� ������ �������� ������� ���� ������ `@'.

����� ��������� ������� ���������, ���������� join �� ��������� SUBSEP, ����� ����� ��������� ����� � ������ ������. ����� ��� ������ ���������� � �������� �����.

/^@c(omment)?[ "t]+file/ " -
if (NF != 3) -
e = (FILENAME ":" FNR ": badly formed `file' line") 
print e ? "/dev/stderr" next "" if ($3 != curfile) -
if (curfile != "")
close(curfile) curfile = $3 ""
for (;;) -
if ((getline line) != 0)
unexpected.eof() if (line ~ /^@c(omment)?[ "t]+endfile/)
break else if (line ~ /^@(end[ "t]+)?group/)
continue if (index(line, "@") == 0) -
print line ? curfile continue
"" n = split(line, a, "@") # ���� a[1] == "", ��� �������� ������� @,
# �� ���������� ��� �������
for (i = 2; i != n; i++) -
if (a[i] == "") - # ���������  @@
a[i] = "@" if (a[i+1] == "")
i++ "" "" print join(a, 1, n, SUBSEP) ? curfile "" ""

����� �������� ������������ ��������������� `?'. �����, ��������� � `?', ��������� ���� ������ ���� ���; �� �������� �������� � ����������� ����� ����������� � ����� ����� (��. ������ 6.6 [��������������� ������ print � printf], ���. 70). ��� ��������� ��� ����� ��������� ����� ��������� � ����������� � ����� � ��� �� ����� ��������� ����� (��� ��� ������� �����!) ��� ������ �����������. ���� ����������� ������ ����� ���������� ��� ������ ����� � �������, ��� �� ����� �������� �����.

�������, ������� unexpected.eof �������� ��������������� ��������� �� ������ � ��������� ���������.

������� END ��������� ������, �������� �������� ����.

function unexpected.eof() -
printf("%s:%d: unexpected EOF or error"n", "
FILENAME, FNR) ? "/dev/stderr" exit 1 ""
END -
if (curfile)
close(curfile) ""

16.2.8 ������� �������� ��������

 

������� sed ���� "�������� ��������," �.�. ���������, ������� ������ ����� ������, ������ ��������� � ���� � �������� ���������� ������ ������. �� ����� ������������� ��� �������� ���������� ��������� � ������� ����� ��� � ������ ������, �������������� ����������� ������.

sed ���� �������� ������� ���������. ��� ������ ������������ ��� ���������� ���������� ����������� � �������� ���������:

command1 ! orig.data -- sed 's/old/new/g' -- command2 ? result

����� `s/old/new/g' ����������� sed ���������� regexp `old' � ������ ������� ������ � �������� ��� ������� `new' ��������� (�.�. ��� ��������� � ������). ��� ������ �� awk-������� gsub (��. ������ 12.3 [���������� ������� ��� �������� �� ��������], ���. 137).

��������� ���������, `awksed.awk', �������� �� ����� ���� ���������� �� ��������� ������: ������� ��� ������ � ����� ��� ��� ������. ������ �������������� ��������� ��������������� ��� ����� ������ � ������� ��� ���������. ���� �� ���, �� ������������ ����������� ����.

# awksed.awk --- ��������� s/foo/bar/g ��������� ������ ������
# ������� Michael Brennan �� ����
# Arnold Robbins, arnold@gnu.org, Public Domain 
# August 1995
function usage() -
print "usage: awksed pat repl [files...]" ? "/dev/stderr" exit 1 ""
BEGIN -
# ��������� � ����������
if (ARGC ! 3)
usage()
RS = ARGV[1] ORS = ARGV[2]
# �� ������������ ��������� ��� �����
 ARGV[1] = ARGV[2] = "" ""
# look ma, no hands! -
if (RT == "")
printf "%s", $0 else

print ""

��������� ���������� �� ����������� gawk ����� RS ��� regexp � �� ��������� � RT ������������ ������, ������������� ������ (��. ������ 5.1 [��� ���� ����������� �� ������], ���. 37).

���� ������� � ���, ����� ������������ RS ��� ������� ��� ������. gawk ����� ������������� ������������� � $0 text, ������������� ����� �������������� � ��������. ���� ����� �� �� ����� ��������. �����, ������������ � ORS ���������� �����, ������� ���������� ������ �� ����� �������� �����, ������� �� ����� ���������, � ����� �� ��� ���������� �����.

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

������ � ���, ���� ���� �� ������������� �������, ������� ������������� RS, � RT ����� ����������� ������ �������. � ���� ������ �� ����� �������� $0, ��������� printf (��. ������ 6.5 [������������ ��������� printf ��� ������������ ������], ���. 64).

������� BEGIN ��������� �����������, �������� ������������ ���������� ���������� � ������� usage � ������ ����������. ����� ��� ������������� RS � ORS �������� ���������� � ��������� ������ � ������������� � ARGV[1] � ARGV[2] ������ �������, ��� ��� ��� �� ����� ��������������� ��� ����� ������ (��. ������ 10.3 [������������� ARGC � ARGV], ���. 120).


������� usage �������� ��������� �� ������ � ���������� ���������� ���������. Finally, the single rule handles the printing scheme outlined above, using print or printf as appropriate, depending upon the value of RT.


16.2.9 ������� ���� ������������� ������������ �������

 

������������� ������������ ������� � awk ����� ���� ����� ��������. ��������� ���������� ����� ��������� � ���������. ������� ���� � ��������� ������ ��������� ������� ����������:

# ������������ �������  
# @include getopt.awk @include join.awk ...
# ������� ���������
BEGIN -
while ((c = getopt(ARGC, ARGV, "a:b:cde")) != -1)
...
... ""

��������� ���������, `igawk.sh', ������������ ����� ������. ��� ���������� ����� � gawk ���������� AWKPATH � ��������� ��������� include; �.�., ����, ������� �������� � ������� `@include', ����� ��� ��������� ���������� ��������� `@include'. igawk ��������� ������ � ����, ����� ��������� �� include ���� ������ ���� ���, ��� ��� ��������� include �� �������� � ���������� ��������� ������������ �������.

igawk ������ ����� ���� ������� �������, ������� gawk. ��� ������, ��� �� ������ ��������� �� ��������� ������ ��� ��������� ��� gawk, ������� ����������� ����� ������� �������� �����, ��������� ����� `-f', � ����������� ��������� ����� �� ��������� ������ � ������������� �������� �������.

��������� �������� � �������������� POSIX Shell (sh) command language. ��� �������� ��������� �������:

1. ������������� ���������, ��������� ���, ��� �� ������������ �������� ��� �������� ���� awk, ��� ������������ ������������� ��� ���������� ����������� ���������.

2. ������ ��������, ������� ��������� � ������ awk, ���������� � ��������� ����, ������� ����� ��������. ������� ��� ������.

a. ���������� �����, �������������� ������� `--source' ��� `--source='. ���� ����� ������ ����������� � echo. ��������� echo ������������� ������ ����������� newline.

b. ����� ������, �������������� � `-f'. �� ���������� ������ ������, � echo ��������� `@include filename' �� ��������� ����. ��������� ��������� ��������� ����� ����� �������� ��� �� ��� �������� gawk, ��� �������� � ��������� ������ �� ����� � ��������� � ������ �����.

3. ����������� ��������� awk-��������� ��� ��������� ������ ��� ���������� ���������� `@include'. ����������� ��������� ���������� �� ������ ��������� ����.

4. ����������� ����������� ��������� � ����������� gawk � ������� ������� ��������� ����������� ��������� ������, ���������� ������������� ( ������ ��� ����� ������ � �������).

��������� ����� ��������� �������� ����� �����������, ���� ������ �������� ��� `debug'. � ��������� ������ �������� �������� trap ���������� ������� ���� ��������� ������ ����� ��������� ��������� ��� ��� �� ����������.

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

-- ��� ��������� ��������� ��� igawk. ��� ��������� ������ ���� �������� ���������������� awk-��������� ��� ������ ���������.

-W ��� ���������, ��� ��������� �������� ������������ ��� gawk. ��� ���������� ��������� `-W' ������������� � ������ ���������� ���������� � �������� ������������. (��� --- ����� � sh-����������������. �� ��������� �� ��� ��������, ���� �� �� ������� � sh.)

-v -F  ��� ��������� ������������ � ����������  gawk.

-f --file --file= -Wfile=   
                ��� ����� ������������ �� ��������� �����
                `/tmp/ig.s.$$' � ����������  `@include'. 
                ������� sed ������������ ���
                �������� ������� ������ � ����������� ����� ����������� 
                (��������,`--file=').

--source --source= -Wsource=   
                ����� source ���������� �� echo � `/tmp/ig.s.$$'.

--version --version -Wversion    
                igawk �������� ����� ������,  ���������
                `gawk --version' ��� ��������� ���������� 
                � ������ gawk � ������ exit.

���� �� ���� `-f', `--file', `-Wfile', `--source', ��� `-Wsource', �� ������ ���������� ������ ���� awk-���������. ���� � ��������� ������ �� ��������� ������� ����������, igawk �������� ��������� �� ������ � ��������� exits. � ��������� ������ ������ �������� ���������� �� echo � `/tmp/ig.s.$$'.

� ����� ������ ����� ��������� ���������� `/tmp/ig.s.$$' �������� ������ ����� �������� awk-���������.

$$' � sh ������������ ����� ID �������� ��������. �� ����� ������������ � ���������� �������� ��� �������� ���������� ���� ��������� ������. ��� ��������� ������ ������������� ��������� igawk, �� �������� � ���������� � ������� ��������� ������.

��� ���� ��������� igawk:

#! /bin/sh
# igawk --- �������  gawk �� ������ ���������  @include
# Arnold Robbins, arnold@gnu.org, Public Domain 
# July 1993
if [ "$1" = debug ] then
set -x shift else
# ������� ��� exit, hangup, interrupt, quit, termination
trap 'rm -f /tmp/ig.[se].$$' 0 1 2 3 15 fi
while [ $# -ne 0 ] # ���� �� ����������
do case $1 in --) shift; break;;
-W) shift
set -- -W"$@" continue;;
-[vF]) opts="$opts $1 '$2'"
shift;;
-[vF]*) opts="$opts '$1'" ;; -f) echo @include "$2" ?? /tmp/ig.s.$$
shift;;
-f*) f=`echo "$1" -- sed 's/-f//'`
echo @include "$f" ?? /tmp/ig.s.$$ ;;
-?file=*) # -Wfile or --file
f=`echo "$1" -- sed 's/-.file=//'` echo @include "$f" ?? /tmp/ig.s.$$ ;;
-?file) # get arg, $2
echo @include "$2" ?? /tmp/ig.s.$$ shift;;
-?source=*) # -Wsource or --source
t=`echo "$1" -- sed 's/-.source=//'` echo "$t" ?? /tmp/ig.s.$$ ;;
-?source) # get arg, $2
echo "$2" ?? /tmp/ig.s.$$ shift;;
-?version)
echo igawk: version 1.0 1?&2 gawk --version exit 0 ;;
-[W-]*) opts="$opts '$1'" ;;
*) break;; esac shift done
if [ ! -s /tmp/ig.s.$$ ] then
if [ -z "$1" ] then
echo igawk: no program! 1?&2 exit 1 else
echo "$1" ? /tmp/ig.s.$$ shift fi fi
# � ���� �����  /tmp/ig.s.$$ �������� ���������.

awk-��������� ��� ��������� �������� `@include' ������ ��������� ������ �� ������� � ������� getline (��. ������ 5.8 [����� ���� � ������� getline], ���. 53). ����� ������� ������ � ��������� `@include' �������������� � ������� �����. ����� �������������� ��������� `@include', ��� �������� ����� �������� �� ���� � ������� ������ ���������� ���, ������� ������ � ��������� `@include'. ����� ���� �������������, �� ����� ����������� ������� ���� � ����� ���������� �������. ������� ����������, ����� � ���� �������� �������� ����.

������� pathto ����������� ������ ���������� ������� ���� � �����. ��� ���������� ��������� gawk ��� ������ ���������� ��������� AWKPATH (��. ������ 14.3 [���������� ��������� AWKPATH], ���. 166). ���� ��� ����� ����� � ���� `/', ����� ���� �� ������������. � ��������� ������ ��� ����� ����������� � ������ ������� �������� �� ���� � �������� ������� ������� ���� � �������������� ��� ������. ������������ ���� � awk ��� �������� ����, ��� ���� ����� ���� �������, ���� ������� ������ ��� �� getline; ��� � ����������� pathto. *5* ���� ���� ��������, �� ����������� � ��� ��� ������������ ��������.

gawk -- ' # ��������� �������� @include
function pathto(file, i, t, junk)

5 � ����� ������ ������� awk ���� `getline junk ! t' ����� �����������, ���� ���� ����������, �� ����.


-
if (index(file, "/") != 0)
return file
for (i = 1; i != ndirs; i++) -
t = (pathlist[i] "/" file) if ((getline junk ! t) ? 0) -
# ���� ������
close(t) return t "" "" return "" ""

������� ��������� ���������� ������ ������� BEGIN. ������, ��� ��� ������, ��� ��������� ������� pathlist, ������� ���������� pathto. ����� ���������� ���� �� `:' ������ �������� ���������� �� "." ������� ������������ ������� �������.

BEGIN -
path = ENVIRON["AWKPATH"] ndirs = split(path, pathlist, ":")
for (i = 1; i != ndirs; i++) -
if (pathlist[i] == "")
pathlist[i] = "." ""

���� ���������������� ��������� ARGV[1], ������� ����� `/tmp/ig.s.$$'. ����� ���� ������� ����. ������� ������ �������� ���� �� ������. ������, ������� �� ���������� � `@include', ���������� ��������. ���� ������ ���������� � `@include', �� ��� ����� ��������� � $2. ���������� pathto ��� ��������� ������� ����. ��� ������� �� �������� ��������� �� ������ � ���������� ������.

���������, ��� ����� �������, ��� ���������, �� ��� �� ���� ���� ������� �����. �������������� ������ ������������ ������� ������� ������� ����������� (�� @inckude) �����, � ���� ���� ��������� ��� �������� ������ ����������. ���� ���� ��� ����������, ���������� �������������� �� ����. � ��������� ������ ����� ���� �������� �� ������� ����� � ������� ������������.

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

stackptr = 0 input[stackptr] = ARGV[1] # ARGV[1] ���� ������ ����

for (; stackptr ?= 0; stackptr--) -
while ((getline ! input[stackptr]) ? 0) -
if (tolower($1) != "@include") -
print continue "" fpath = pathto($2) if (fpath == "") -
printf("igawk:%s:%d: cannot find %s"n", "
input[stackptr], FNR, $2) ? "/dev/stderr" continue ""
if (! (fpath in processed)) -
processed[fpath] = input[stackptr] input[++stackptr] = fpath "" else
print $2, "included in", input[stackptr], "
"already included in", " processed[fpath] ? "/dev/stderr" ""
close(input[stackptr]) "" ""' /tmp/ig.s.$$ ? /tmp/ig.e.$$

��������� ��� ������� � ������ gawk ��� ���������� ����������� ��������� � ������������� ����������� � ����������� ��������� ������, ���������� �������������. ������ ��� ��������� gawk ���������� ������� � ������ ��������� igawk.

eval gawk -f /tmp/ig.e.$$ $opts -- "$@"
exit $?

����������� ������ igawk ������������ ��� ������ ������� ���� ���������. ������� ��� �������� ���������, ������� ���������� ��������� �������� �����.

1. ������������� `@include' ���� ��� ������, ��������� � `-f', ������ ���������� �������� ��������� awk-��������� ����� ����� �������; ��� `@include' �������������� �� ���� ���.

2. ������� pathto �� ��������� ��������� ������, ���������� getline ��� �������� ����������� ����� . ������� ��������� ��� ������ ��� ������������� � ������� ���������� ����������� ��������� ������.

3. ������������� ����� getline � ������� BEGIN ��������� ������� ��� ��� � ����� �����. ��� ������������� ���������� ��������� ���� ��� ��������� ��������� �������� `@include'.

����, ��� ��������� ������������, ��� ����� ����� ������������� ��������� �� sh � awk ������. ������ ��� ������� ������� �������� ������, �� �������� � ���������������� �� ������ ������ � ������� �� ��� ��++, � ��� ���� ����� ����� �������� ������������� ���� ������� � �������������� �����������, ��������� ��������, ��� ��� �������� � awk.

�������, igawk ����������, ��� �� ������ ���������� ��������� ����� ����� � ���������; ����� ��� ��� ����� ����� ��������. ��� �������� igawk, �� ��� ������ ������ ������� ��������� `@include' � ����� gawk.

��� �������������� ������ � ����������, ���������� ���� ����� ��� ����� � �������� �� ���� ������.

`default.awk'

���� ���� ������ ��������� �� ��������� ����� ��������� ������������ �������, ����� ��� getopt � assert.

`site.awk'

���� ���� ������ ��������� ������������ �������, ������� ���������� ��� ����� ��� ���������, �.�. �������� ������������� �������. ���� ��������� ����, ����� �������� `default.awk' �������� ����� �������� gawk, �� ������ �� ���������� �������������� ��������� ��� ������ ��� ����������� ��������� �������.

���� ������������ ���������, ����� gawk ��� ������������� �������������� ������� ���� ������ ��� ������ �������. ������ �����, ���� �� ����� ������ ������������ ��� ����� igawk. ��������� igawk ����� ������������ ��������� ��������� `@include', �� `default.awk' ����� ������ ��������� ��������� `@include' ��� ����������� ������������ �������.