П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
Поиск по сайту:
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое








Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 4072 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 6722 раз(а).

Учебник HTML.
Просмотров 3693 раз(а).

Руководство по PHP5.
Просмотров 5966 раз(а).

Хостинг через призму DNS.
Просмотров 4773 раз(а).

Подборка текстов стандартных документов.
Просмотров 56218 раз(а).

Учебник PHP - Самоучитель
Просмотров 3665 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 8250 раз(а).

Внешние атаки...
Просмотров 4517 раз(а).

Учебник PHP.
Просмотров 3154 раз(а).

SSI в примерах.
Просмотров 161 раз(а).



 
 
| Добавить в избранное | Сделать стартовой | Помощь





Руководство пользователя для GNU Awk

16. Практические awk-программы

16.1 Переизобретение колеса для забавы и пользы

16.1.6 Печать, не дуплицированных строк текста

Утилита uniq читает отсортированные строки текста данных из стандартного ввода и (по умолчанию) удаляет дублированные строки. Другими словами, печатаются только уникальные строки. Отсюда и имя утилиты. uniq имеет несколько параметров. Она вызывается так:

uniq [-udc [-n]] [+n] [ input file [ output file ]]
Параметры имеют следующий смысл:

-d   Печать только повторенных строк.
-u   Печать только неповторяющихся строк.
-c   Считать строки. Этот параметр подавляет `-d' и `-u'. 
	 Считаются как повторяющиеся, так 
	 и неповторяющиеся строки.

-n   Пропустить  n полей перед сравнением строк. 
	Определение полей  по
	правилу умолчания в awk: не-whitespace символы, 
	отделенные группами
	пробелов и/или tab.

+n   Пропустить n символов перед сравнением строк. 
	Предварительно пропускаются
	поля, указанные параметром `-n'.

input file  Входные данные читаются из входного файла, 
	названного в командной
	строке, а не из стандартного ввода.

output file  Генерированный вывод направляется 
	в названный выходной файл,
	а не в стандартный вывод.

Нормально uniq работает так, как будто присутствуют оба параметра `-d' и `-u'.

Приведем awk-реализацию uniq. Она использует библиотечную функцию getopt (см. раздел 15.10 [Обработка параметров командной строки, стр. 186), и библиотечную функцию join (см. раздел 15.6 [Соединение элементов массива в цепочку], стр. 176).

Программа начинается с функции usage, затем следует краткий обзор параметров и комментарий об их назначении.

Правило BEGIN работает с аргументами командной строки и параметрами. Оно использует уловку, чтобы заставить getopt действовать с параметрами формы `-25', рассматривая такой параметр как параметр-букву `2' с аргументом `5'. Если действительно были указаны две или более цифр (Optarg выглядит как число), Optarg сцепляется с цифрой параметра и затем результат складывается с нулем для превращения его в число. Если имеется только одна цифра в параметре, то Optarg не нужен и Optind должен быть уменьшен так, что getopt будет обрабатывать его в следующий раз. Так что этот код в некоторой степени необычный.

Если параметров нет, по умолчанию печатаются и повторенные и не повторенные строки. Выходной файл, если указан, присваивается в outputfile. Ранее outputfile инициализировался как стандартный вывод , `/dev/stdout'.

# uniq.awk --- модель uniq в awk
# Arnold Robbins, arnold@gnu.org, Public Domain 
# May 1993
function usage( e) -
e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
print e ? "/dev/stderr" exit 1 ""
# -c счет строк. подавляет -d и -u 
# -d только повторные строки
# -u только не повторяющиеся строки
# -n пропустить n полей
# +n пропустить  n символов, но сначала пропускать поля
BEGIN " -
count = 1 outputfile = "/dev/stdout" opts = "udc0:1:2:3:4:5:6:7:8:9:"
while ((c = getopt(ARGC, ARGV, opts)) != -1) -
if (c == "u")
non.repeated.only++ else if (c == "d")
repeated.only++ else if (c == "c")
do.count++ else if (index("0123456789", c) != 0) -
# getopt требует аргументы к параметрам
# это запутывает нас с аргументами вроде -5
if (Optarg ~ /^[0-9]+$/)
fcount = (c Optarg) + 0 else -
fcount = c + 0 Optind-- "" "" else
usage() ""
if (ARGV[Optind] ~ /^"+[0-9]+$/) -
charcount = substr(ARGV[Optind], 2) + 0 Optind++ ""
for (i = 1; i ! Optind; i++)
ARGV[i] = ""
if (repeated.only == 0 && non.repeated.only == 0)
repeated.only = non.repeated.only = 1
if (ARGC - Optind == 2) -
outputfile = ARGV[ARGC - 1] ARGV[ARGC - 1] = "" "" ""

Следующая функция, are.equal, сравнивает текущую строку, $0, с предыдущей строкой, last. Она реализует пропуск полей и символов. Если не были заказаны ни счет полей ни счет символов, то are.equal просто возвращает 1 или 0 в зависимости от результата простого сравнения last и $0. В противном случае действия усложняются. Если должны быть пропущены поля, каждая строка превращается в массив с помощью split (см. раздел 12.3 [Встроенные функции для действий с цепочками], стр. 137), и затем нужные поля опять соединяются в строку с помощью join. Полученные строки поступают в clast и cline. Если никакие поля не пропускаются, в clast и cline устанавливаются last и $0 соответственно. Наконец, если пропускаются символы, используется substr для удаления ведущих charcount символов в clast и cline. Затем две цепочки сравниваются и are.equal возвращает результат сравнения.

function are.equal( n, m, clast, cline, alast, aline) -
if (fcount == 0 && charcount == 0)
return (last == $0)
if (fcount ? 0) -
n = split(last, alast) m = split($0, aline) clast = join(alast, fcount+1, n)
cline = join(aline, fcount+1, m) "" else -
clast = last cline = $0 "" if (charcount) -
clast = substr(clast, charcount + 1) cline = substr(cline, charcount + 1) ""
return (clast == cline) ""

Два следующие правила составляют тело программы. Первое выполняется только для самой первой строки данных. Оно устанавливает last равным $0, для сравнения с последующими строками текста.

Второе правило выполняет всю работу. Переменная equal будет 1 или 0 в зависимости от результатов сравнения, выдаваемых функцией are.equal. Если uniq учитывает повторяющиеся строки, то переменная count увеличивается при равенстве строк. В противном случае строка печатается и count сбрасывается, поскольку две строки не равны.

Если uniq не подсчитывает, count увеличивается, если строки равны. Иначе, если uniq подсчитывает повторные строки и более чем одна строка была замечена, или если uniq считает неповторяющиеся строки и только одна строка имеется, то строка печатается и count сбрасывается.

Наконец, подобная же логика используется в правиле END для печати последней строки в входных данных.

NR == 1 -
last = $0 next ""
-
equal = are.equal()
if (do.count) - # overrides -d and -u
if (equal)
count++ else -
printf("%4d %s"n", count, last) ? outputfile
last = $0 count = 1 # reset "" next ""
if (equal)
count++ else -
if ((repeated.only && count ? 1) ----
(non.repeated.only && count == 1))
print last ? outputfile last = $0 count = 1 "" ""
END -
if (do.count)
printf("%4d %s"n", count, last) ? outputfile else
if ((repeated.only && count ? 1) ----
(non.repeated.only && count == 1)) print last ? outputfile ""

Назад | Вперед
Содержание (общее) | Содержание раздела | Содержание подраздела



Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
 





Copyright © 2005-2016 Project.Net.Ru