- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания UNIX — универсальная среда программирования - Брайан Керниган
Шрифт:
Интервал:
Закладка:
$ sed 1q /etc/passwd | awk '{split($0, a, ":"); print a[1]}'
root
$ echo 9/29/83 | awk '{split($0, date, "/"); print date[3]}'
83
$
В табл. 4.5 перечислены встроенные функции awk.
cos(expr) Косинус expr exp(expr) Возведение в степень expr getline() Чтение следующей входной строки; возвращает 0 в случае конца файла, в противном случае 1 index(s1, s2) Положение строки s2 в s1; возвращает 0, если строка не входит int(expr) Целая часть expr; округляет по минимуму length(s) Длина строки s log(expr) Натуральный логарифм expr sin(expr) Синус expr split(s, a, c) Разбиение s на а[1] ... a[n] по символу c; возвращает n sprintf(fmt, ...) Форматирование в соответствии со спецификацией fmt substr(s,m,n) Подстрока в n символов строки s, начинающаяся с индекса mТаблица 4.5: Встроенные функции awk
Ассоциативные массивыСтандартной задачей обработки данных является получение суммарных значений для множества пар имя значение. Иными словами, по входному потоку типа
Susie 400
John 100
Mary 200
Mary 300
John 100
Susie 100
Mary 100
мы хотим получить суммарные значения для каждого имени:
John 200
Mary 600
Susie 500
Программа awk предлагает изящное решение этой задачи — с помощью ассоциативных массивов. Хотя обычно мы представляем себе индекс массива как целое число, в awk любое значение можно использовать в качестве индекса. Поэтому
{sum[$1] += $2}
END {for (name in sum) print name sum [name]}
задает всю программу подсчета n печати сумм для пар имя значение независимо от порядка следования этих пар. Каждое имя ($1) служит индексом в массиве sum; в конце применена специальная форма цикла for для перебора всех элементов sum и их печати. Синтаксис этого варианта цикла for таков:
for (перем in массив)
оператор
Хотя он может показаться вам искусственным, как цикл for языка shell, они никак не связаны. Цикл охватывает индексы массива, а не его элементы, устанавливая значение "перем" равным каждому индексу поочередно. Однако порядок появления индексов непредсказуем, поэтому может возникнуть необходимость в их сортировке. В приведенном примере выходной поток можно по конвейеру передать команде sort, чтобы имена шли в порядке убывания значений:
$ awk '...' | sort +1nr
Реализация ассоциативной памяти предполагает хэширование, чтобы доступ к одному элементу занимал столько же времени, сколько и к любому другому, и чтобы это время не зависело (по крайней мере для массивов средних размеров) от числа элементов в массиве.
Использование ассоциативных массивов эффективно для вычислительных задач, таких, как подсчет частоты появления слов во входном потоке:
$ cat wordfreq
awk ' { for (i = 1; i <= NF; i++) num[$i]++ }
END {for (word in num) print word, num[word] }
' $*
$ wordfreq ch4.* | sort +1 -nr | sed 20q | 4
the 372 .CW 345 of 220 is 185
to 175 a 167 in 109 and 100
.PI 94 .P2 94 .PP 90 $ 87
awk 87 sed 83 that 76 for 75
The 63 are 61 line 55 print 52
$
В первом цикле for выбирается каждое слово из входной строки и заполняется массив num, индексируемый словами. (Не путайте $i, обозначающее в awk i-е поле входной строки, с переменными языка shell.) После того как файл будет прочитан, во втором цикле for печатаются в произвольном порядке слова и частота их появления.
Упражнение 4.9В результат действия команды wordfreq попали команды форматирования типа .CW, которые применяются для печати слов определенным шрифтом. Как избавиться от таких ненастоящих слов? Как бы вы использовали команду tr, чтобы программа wordfreq работала правильно, независимо от того, прописные или строчные буквы задействованы во входном потоке? Сравните реализацию и скорость выполнения программы wordfreq, конвейера из разд. 4.2 и предлагаемого ниже решения.
sed 's/[→][→]*/
/q' $* | sort | uniq -c | sort -nr
СтрокиХотя обе команды, и sed и awk, предназначены для решения небольших задач типа выбора определенного поля, только awk используется в той степени, в какой предполагает настоящее программирование. Примером может служить программа, которая разбивает длинные строки, чтобы они занимали не более 80 позиций. Каждая строка, превышающая 80 символов, завершается после 80-го символа; в качестве предупреждения добавляется и обрабатывается остаток строки. Хвост разбиваемой строки сдвигается к ее правому концу, а не к левому, что более удобно для программ печати, и именно поэтому мы обратимся к программе fold. Рассмотрим, в частности, строки из 20, а не из 80 позиций:
$ cat тест
Короткая строка
Строка немного длиннее
Эта строка еще длиннее, чем предыдущая строка
$ fold тест
Короткая строка
Строка немного длиннее
Эта строка еще длиннее,
чем предыдущая строка
$
Вам может показаться странным, что в седьмой версии системы нет программы для добавления или удаления символов табуляции, хотя команда pr в System V выполняет и то и другое. Наша реализация программы fold использует редактор sed, чтобы перевести символы табуляции в пробелы и чтобы счетчик числа символов в awk принял правильное значение. Это хороший способ при табуляции в начале строки (что типично для языковых программ), но номер позиции сбивается, если символ табуляции оказывается в середине строки:
# fold: fold long lines
sed 's/(->/ /g' $* | # convert tabs to spaces
awk '
BEGIN {
N = 80 # folds at column 80
for (i = 1; i <= N; i++) # make a string of blanks
blanks = blanks " "
}
{
if ((n = length($0)) <= N)
else {
for (i = 1; n > N; n -= N) {
printf "%s\n", substr($0,i,N)
i += N;
}
printf "%s%sn" , substr(blanks, 1, N-n), substr($0, I)
}
} '
На языке awk нет явной операции конкатенации строк; строки соединяются, если они следуют подряд. Вначале blanks является пустой строкой. Цикл в части BEGIN создает длинную строку пробелов конкатенацией: каждый шаг цикла прибавляет еще один пробел к концу строки blanks. Во втором цикле входная строка разбивается на части, пока оставшаяся часть не станет достаточно короткой. Как и в языке Си, операцию присваивания можно использовать в качестве выражения, поэтому в конструкции
if ((n=length($0)) <= N)...
длина входной строки присваивается n до проверки значения. Обратите внимание на скобки.
Упражнение 4.10Измените программу fold так, чтобы разрыв строки происходил на пробеле или символе табуляции, а не посреди слова. Сделайте эту программу пригодной и для длинных слов.
Взаимодействие с интерпретаторомДопустим, что вы намереваетесь написать программу field n. Эта программа будет печатать n-е поле каждой входной строки так, чтобы можно было, например, задать:
$ who | field 1
для печати только имен, под которыми пользователи входят в систему. Язык awk явно предоставляет возможность выбора полей. Наша основная задача — передать номер n программе awk. Ниже приведено одно из возможных решений:
$ awk '{print $'$1'}'
Здесь $1 открыто (не внутри каких либо кавычек), и поэтому становится номером поля, доступным в программе awk. При ином решении используются кавычки:
awk "{print $$1}"
Аргумент обрабатывается интерпретатором, поэтому $ становится $, а $1 заменяется на значение n. Мы предпочитаем решение с апострофами (одиночными кавычками), поскольку при использовании кавычек в типичной программе awk появится слишком много символов .