Введение в UNIX
Дегтярев Е.К.
Оглавление
10. Работа с текстовыми файлами
При разработке и документировании программного обеспече-
ния неожиданно большое время занимает работа по созданию,
анализу, проверке и исправлению текстовых файлов. Она выпол-
няется достаточно простыми средствами печати файлов, поиска
строк, замены букв и строк, сравнения файлов и тому подоб-
ное. Соответствующие утилиты весьма эффективны для выполне-
ния таких работ по сравнению с обычным текстовым редактором.
В начало страницы
Простейший способ печати - это перенаправление стандарт-
ного вывода команды cat на терминал, имеющий устройство пе-
чати.
Например:
$ cat file > /dev/lp.
Однако не все терминалы имеют собственное устройство пе-
чати. В случае общего устройства печати система обеспечивает
его коллективное использование, при котором заявка на пе-
чать, заставшая устройство занятым, ставится в очередь до
момента освобождения устройства, после чего ее требование
удовлетворяется автоматически. В этом случае используется
команда lpr или lp.
Например:
$ lpr file1 file2 file3
Имеются также команды просмотра очереди заявок на печать
lpstat и удаления заявки из очереди (cancel). Команды lpr и
lp не обеспечивают разбиение печати на страницы. Это может
быть сделано командой pr подготовки (prepare) файла для
постраничной печати, которая предшествует печати.
Пример:
$ pr myfyle | lpr.
Размеры страницы по умолчанию равны 66 строкам (длина -
length) по 72 знака (ширина - width). Ключами -w и -l можно
задать другие размеры.
Примеры:
$ pr -w 132 -h"Conversion program" conv.c | lpr
$ pr -l 25 addr | lpr
Ключ -h (head) вводит заголовок печати. Двойные кавычки
требуются при наличии в заголовке пробелов, иначе они могут
быть опущены.
В начало страницы
Многие команды ограничивают размеры файла, который они
могут обработать. Если ваш файл слишком велик, вы можете
разбить его на части командой split, а впоследствии после
обработки собрать из этих частей командой cat. Каждая часть
становится независимым файлом с именами по умолчанию xaa,
xab, xac, ..., xzz. Размер части по умолчанию - 1000 строк.
Пример:
$ split bigfile.
Можно изменить размер по умолчанию, задавая его явно,
например, 500 строк:
$ split -500 bigfile.
Можно задавать имена частей, например:
$ split bigfile ribs.
В этом случае имена будут ribsaa, ribsab, ... ribszz.
После необходимой обработки всех или некоторых частей
сборка файла из частей выполняется, например, следующим об-
разом:
$ cat ribs?? > bigfile.new,
где знаки вопроса - метасимволы, обозначающие любой символ.
Типичным примером применения технологии разборки - сборки
является печать отдельных избранных страниц файла.
Пример:
$ pr bigfile > bigpr
$ split -66 bigpr
$ lpr xaf xaj
Здесь будут напечатаны 6-я и 10-я страницы размером 66
строк исходного файла.
В начало страницы
Утилита sort упорядочивает записи файла в алфавитно-циф-
ровом порядке.
Пример:
$ sort people
Bill Williams 100
Henry Morgan 112
Mary Clark 101
$
Записи отсортированы по первой букве имени. Однако можно
выполнить сортировку и по фамилиям:
$ sort +1 people
Mary Clark 102
Henry Morgan 112
Bill Williams 100
$
Ключ +1 означает, что одно поле с начала записи было иг-
норировано при сортировке.
Сортировка по третьему полю с игнорированием лидирующих
пробелов выполняется с использованием ключа - b (blank):
$ sort -b +2 people
Bill Williams 100
Mary Clark 101
Henry Morgan 112
$
Для сохранения результата сортировки в файле используется
ключ -o (output):
sort -o sortpeople +1 people
Для слияния уже отсортированных файлов используется ключ
-m.
Пример:
$ sort +1 admpeople > sortadm
$ sort +1 hardpeople > sorthard
$ sort +1 sortpeople > sortsoft
$ sort -m +1 sortadm, sorthard, sortsoft > sortall
$
Имеется возможность удаления дублированных записей, ис-
пользуя ключ -u (uniq), а также сортировки по нескольким
несмежным полям.
В начало страницы
Подсчет числа строк, слов и знаков в заданном файле вы-
полняется командой wc.
Например:
$ wc people
3 9 51 people
$
Ключи - l (lines), - w (words) - c (character) могут ука-
зать явно объекты счета.
Например:
$ wc -l people
3 people
$ wc -lc people
10 51 people
$
В начало страницы
Утилита grep осуществляет поиск по одному или нескольким
файлам и печатает все строки, содержащие предъявленный обра-
зец текста, на стандартном выводе.
В простейшем случае образец задается постоянной строкой
знаков. В общем же случае он задается регулярным выражением
(grep - акроним от global regular expression printer).
Пример:
$ grep Henry admpeople hardpeople softpeople
Softpeople: Henry Morgan 112
$
Или:
$ grep Henry *people
Softpeople: Henry Morgan 112
$
Ключ -v (invert) предписывает печать всех строк, кроме
найденных, например:
$ grep -v "Henry Morgan" Softpeople
Bill Williams 100
Mary Clark 101
$
Двойные кавычки требуются для размещения в образце пробе-
лов.
Регулярные выражения позволяют вести поиск типа: найти
все слова из четырех букв, начинающиеся на d, или все слова,
кончающиеся на able, и тому подобное. Рассмотрим примеры за-
дания образцов посредством регулярных выражений.
Знаки ^ и $ помечают начало и конец строки соответственно:
"^Genesis" - найти все строки, начинающиеся словом
Genesis;
"eschatus$" - найти все строки, кончающиеся словом
eschatus;
"^Out in cold$" - найти все строки, равные образцу.
Точка помечает любую букву:
"d..." - найти все слова из 4 букв, начинающиеся с d;
"d...$" - то же в конце строки;
"d..\ ." - найти все слова из 4 букв, начинающиеся с d и
оканчивающиеся точкой (знак \ - обратный слэш - отменяет
специальное значение следующего символа).
Квадратные скобы задают возможные значения знака:
"^ [abcxyz]" - найти все строки, начинающиеся с букв
a,b,c,x,y или z:
"[^Dd][a-z][a-z][a-z]" - найти все слова из 4 букв, не
начинающиеся с D или d, в которых последние три буквы - ма-
лые (от a до z).
Фигурные скобки задают количество повторений (замыкание)
предыдущего знака:
"[^Dd][a-z]{3}" - то же самое, что и предыдущий пример;
"[a-z]{3,5}" - найти все слова, содержащие от 3 до 5 ма-
лых букв.
Частные случаи замыкания обозначаются специальным обра-
зом:
* для {0} - ноль и более раз;
+ для {1} - один и более раз;
? для {0,1} - ноль или один раз.
Например:
$ grep ".*" people - просто напечатает все строки файла.
Примеры использования регулярных выражений:
уничтожить все пустые строки в файле:
$ grep -v "^ $" file > newfile;
уничтожить все строки, состоящие только из пробелов:
$ grep -v "^ *$" file > newfile.
В начало страницы
Утилита tr работает со стандартным вводом и имеет два ар-
гумента, задающие упорядоченные множества знаков, в которых
каждый знак первого множества заменяется соответствующим
знаком второго.
Пример:
$ tr a-z A-Z < people
MARY CLARK 101
HENRY MORGAN 112
BILL WILLIAMS 100
$
Ключ -d позволяет задать множество символов, которые бу-
дут уничтожены.
Например:
$ tr -d 0-9 < people
Mary Clark
Henry Morgan
Bill Williams
$
В начало страницы
В процессе разработки программного обеспечения возникает
необходимость сравнения версий файла на разных этапах его
разработки. Узнать, чем версии отличаются друг от друга,
удобно командой diff, которая показывает разницу
(difference) двух файлов; сравнение файлов осуществляется по
строкам (записям). В результате выполнения команды печатают-
ся строки измененные (c), уничтоженные (d) и добавленные (a)
во втором файле-аргументе по сравнению с первым.
Пример:
$ cat people
Mary Clark 101
Sally Smith 113
Jane Buily 121
$ cat people.new
Mary Clark 101
Sally White 113
James Walker 112
$ diff people people.new
2 c 2
Sally White 113
3 d 2
James Walker 112
Знаки < и > означают удаление и добавление строк; команда
показывает также номера строк, в которых найдены отличия.
Если строки отличаются только числом разделяющих слова
пробелов, также отличия можно подавить ключом -b (blank).
Например:
$ diff -b oldfile newfile
$.
Другая возможность быстрого сравнения файлов - команда
cmp (compare), реализованная на основе побайтового (побук-
венного) сравнения двух файлов.
Пример:
$ cmp people people.new
people, people.new differ: char 17, line 2
В качестве результата печатается число отличающихся бай-
тов (букв) и строк (линий).
Ключ -l (long) позволяет распечатать разницу файлов в ви-
де байтов (адрес и отличающиеся значения).
Например:
$ cmp people people, new
26 123 127
27 155 150
30 150 155
- - - - - - - -
197 60 61
198 60 61
Если файлы сильно отличаются друг от друга, сравнить их
эффективнее командой comm (common), которая показывает, что
в двух файлах одинаковое общее.
Например:
$ cat people
Mary Clark 101
Sally Smith 113
Jane Baily 121
$ cat people.new
Mary Clark 101
Sally White 113
James Walker 112
$ comm people people.new
Mary Clark
Sally Smith
Sally White
Jane Baily
James Walker
Результат команды comm печатается в три колонки: строки
первого файла, отсутствующие во втором: строки второго фай-
ла, отсутствующие в первом, и строки, общие для двух файлов.
Можно подавить печать одного или двух столбцов, указывая
его номер в виде ключа, например (печать только третьего
столбца):
$ comm -12 people people.new
Mary Clark
$
В начало страницы
Awk - утилита, подобная grep. Однако, кроме поиска по об-
разцу, она позволяет проверять отношения между полями строк
(записей) и выполнять некоторые действия над строками (гене-
рировать отчеты). Название не является акронимом, оно обра-
зовано первыми буквами фамилий авторов (A.V.Aho,
P.Y.Weinberger, B.W.Kernighan).
Задание поиска-действия следует синтаксису:
/<образец>/{<действие>}
И образец, и действие могут отсутствовать. Найденные по
образцу строки при отсутствии заданного действия выводятся в
стандартный вывод (на экран).
Образец задается регулярным выражением, как и в grep. Ес-
ли образец отсутствует, обрабатываются все строки.
Рассмотрим примеры действий, которые можно выполнить ко-
мандой awk.
Перестановка полей строки выполняется с помощью ссылки на
поле $n, где n - номер поля.
Например:
$ cat people
Mary Clark 101
Henry Morgan 112
Bill Williams 100
$ awk '{print $2 "," $1 "^I" $3}' people
Clark, Mary 101
Morgan, Henry 112
Williams, Bill 100
где ^(control - I) - знак табуляции для подвода каретки к
очередной позиции табуляции (для выравнивания третьего поля).
Действия для awk могут быть заданы в файле.
Например:'
$ cat swap
{print $2 "," $1 "^I" $3}
$ awk -f swap people
Awk имеет встроенные образцы и переменные. Образцы BEGIN
и END означают начало и конец файла соответственно. Перемен-
ная NR (Number of Records) означает число записей (строк) в
файле, NF - число полей в записи. Можно использовать пере-
менные, объявленные пользователем. Пример, подсчитывающий
среднее значение третьего поля файла tennis (программа дейс-
твий для awk - в файле average):
$ cat > average
{total = total + $3}
END {print "Average value is", total/NR}
^D
$ awk -f average tennis
Average value is 8.9
$
Образец поиска в awk может содержать условные выражения.
Пример, в котором в файле tennis пишутся все записи, значе-
ние третьего поля в которых не меньше 10:
$ awk '$3 >= 10 {print $0}'tennis
Steve Daniel 11
Hank Parker 18
Jack Austen 14
$
Знак $0 (доллар-ноль) есть ссылка на всю запись (строку).
В общем случае выражение для условия подчиняется синтак-
сису, близкому к синтаксису выражений в языке C. Кроме того,
в команде awk допустимо указывать отрезок образцов. Пример
выборки всех записей, сделанных с 1976 до 1978 г.:
$ sort -n -o chard.s chard
$ awk '/1976/, /1978/ {if($2 < 8.00 print $0}' chard.s
1976 7.50 Chateau
1977 7.75 Chateau
1978 5.99 Charles
Как видно из примера, в программах действий для awk можно
использовать управляющие структуры с синтаксисом, близким к
языку C.
Пример цикла для печати полей всех записей файла в обрат-
ном порядке:
$ awk {for (i = NF; i > 0; --i) print $i} f1,
где NF - число полей в записи.
Полное описание средств awk можно найти в статье авторов
[6].
В начало страницы
|