Если обработать наш файл distros.txt программой expand, мы сможем использовать cut -c для извлечения любых диапазонов символов из файла. Например, с помощью следующей команды можно извлечь год выпуска из нашего файла со списком, применив cut для извлечения всех символов с 23-й позиции до конца строки:
[[email protected] ~]$ expand distros.txt | cut -c 23-
В состав пакета coreutils входит также программа unexpand, замещающая пробелы символами табуляции.
paste — слияние строк из файлов
Команда paste выполняет операцию, обратную команде cut. Вместо извлечения колонок текста из файла она добавляет одну или несколько колонок текста в файл. Для этого она читает содержимое нескольких файлов, комбинирует поля, найденные в них, и выводит результат в стандартный вывод. Подобно программе cut, paste принимает несколько файлов в аргументах и/или данные со стандартного ввода. Для демонстрации возможностей программы paste выполним небольшую хирургическую операцию с файлом distros.txt, чтобы получить список выпусков в хронологическом порядке.
Сначала применим команду sort, чтобы получить список дистрибутивов, отсортированный по дате выпуска, и сохраним результат в файле distros-by-date.txt:
[[email protected] ~]$ sort -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt > distros-bydate.txt
Затем с помощью cut извлечем два первых поля (с именами дистрибутивов и номерами версий) и сохраним результат в файле distro-versions.txt:
[[email protected] ~]$ cut -f 1,2 distros-by-date.txt > distros-versions.txt
[[email protected] ~]$ head distros-versions.txt
Fedora 10
Ubuntu 8.10
SUSE 11.0
Fedora 9
Ubuntu 8.04
Fedora 8
Ubuntu 7.10
SUSE 10.3
Fedora 7
Ubuntu 7.04
В заключение этапа подготовки извлечем даты выпусков и сохраним их в файле distro-dates.txt:
[[email protected] ~]$ cut -f 3 distros-by-date.txt > distros-dates.txt
[[email protected] ~]$ head distros-dates.txt
11/25/2008
10/30/2008
06/19/2008
05/13/2008
04/24/2008
11/08/2007
10/18/2007
10/04/2007
05/31/2007
04/19/2007
Теперь у нас есть все необходимое. Чтобы завершить процедуру, с помощью paste добавим колонку с датами перед названиями и номерами версий дистрибутивов, создав хронологический список. Для этого достаточно просто вызвать paste и передать ей файлы в требуемом порядке.
[[email protected] ~]$ paste distros-dates.txt distros-versions.txt
11/25/2008 Fedora 10
10/30/2008 Ubuntu 8.10
06/19/2008 SUSE 11.0
05/13/2008 Fedora 9
04/24/2008 Ubuntu 8.04
11/08/2007 Fedora 8
10/18/2007 Ubuntu 7.10
10/04/2007 SUSE 10.3
05/31/2007 Fedora 7
04/19/2007 Ubuntu 7.04
12/07/2006 SUSE 10.2
10/26/2006 Ubuntu 6.10
10/24/2006 Fedora 6
06/01/2006 Ubuntu 6.06
05/11/2006 SUSE 10.1
03/20/2006 Fedora 5
join — объединение строк из двух файлов по общему полю
Программа join действует подобно paste, в том смысле, что она добавляет колонки в файл, но делает это по-своему. Операция join у многих ассоциируется с реляционными базами данных, где она объединяет записи из нескольких таблиц по общему ключевому полю. Программа join выполняет ту же операцию. Она объединяет данные из множества файлов, опираясь на общее ключевое поле.
Чтобы понять, как действует операция join в реляционной базе данных, представьте очень маленькую базу данных с двумя таблицами, по одной записи в каждой. Первая таблица, с именем CUSTOMERS, имеет три поля: номер клиента (CUSTNUM), имя клиента (FNAME) и фамилия клиента (LNAME):
CUSTNUM FNAME LNAME
========= ====== ======
4681934 John Smith
Вторая таблица, с именем ORDERS, имеет четыре поля: номер заказа (ORDERNUM), номер клиента (CUSTNUM), количество (QUAN) и пункт заказа (ITEM):
ORDERNUM CUSTNUM QUAN ITEM
========== ========= ===== ====
3014953305 4681934 1 Blue Widget
Обратите внимание, что обе таблицы имеют общее поле CUSTNUM. Это важно, так как оно устанавливает отношение между таблицами.
Применив операцию join, мы сможем объединить поля из двух таблиц, чтобы получить желаемый результат, например, для подготовки накладной. Проверяя совпадение значений в полях CUSTNUM обеих таблиц, операция join выдаст следующий результат:
FNAME LNAME QUAN ITEM
====== ====== ===== ====
John Smith 1 Blue Widget
Для демонстрации программы join нам понадобится пара файлов с общим ключом. Возьмем в качестве отправной точки файл distros-by-date.txt и из него сконструируем два дополнительных файла. Первый будет содержать даты выпусков (которые в этом примере будут играть роль общего ключа) и названия дистрибутивов:
[[email protected] ~]$ cut -f 1,1 distros-by-date.txt > distros-names.txt
[[email protected] ~]$ paste distros-dates.txt distros-names.txt > distros-key-names.txt
[[email protected] ~]$ head distros-key-names.txt
11/25/2008 Fedora
10/30/2008 Ubuntu
06/19/2008 SUSE
05/13/2008 Fedora
04/24/2008 Ubuntu
11/08/2007 Fedora
10/18/2007 Ubuntu
10/04/2007 SUSE
05/31/2007 Fedora
04/19/2007 Ubuntu
И второй — даты выпусков и номера версий:
[[email protected] ~]$ cut -f 2,2 distros-by-date.txt > distros-vernums.txt
[[email protected] ~]$ paste distros-dates.txt distros-vernums.txt > distros-keyvernums.txt
[[email protected] ~]$ head distros-key-vernums.txt
11/25/2008 10
10/30/2008 8.10
06/19/2008 11.0
05/13/2008 9
04/24/2008 8.04
11/08/2007 8
10/18/2007 7.10
10/04/2007 10.3
05/31/2007 7
04/19/2007 7.04
Теперь у нас есть два файла с общим ключом (поле «дата выпуска»). Здесь важно отметить, что файлы должны быть отсортированы по ключевому полю, чтобы программа join выдала правильный результат.
[[email protected] ~]$ join distros-key-names.txt distros-key-vernums.txt | head
11/25/2008 Fedora 10
10/30/2008 Ubuntu 8.10
06/19/2008 SUSE 11.0
05/13/2008 Fedora 9
04/24/2008 Ubuntu 8.04
11/08/2007 Fedora 8
10/18/2007 Ubuntu 7.10
10/04/2007 SUSE 10.3
05/31/2007 Fedora 7
04/19/2007 Ubuntu 7.04
Отметьте также, что по умолчанию в качестве разделителя полей во входных данных join использует символы табуляции, а в выводе — пробел. Такое поведение можно изменить с помощью параметров. За дополнительными подробностями обращайтесь к странице справочного руководства (man) для join.
Сравнение текста
Довольно часто бывает необходимо сравнить версии текстовых файлов. Для системных администраторов и разработчиков программного обеспечения это особенно важно. Системному администратору, например, может понадобиться сравнить имеющийся конфигурационный файл с предыдущей версией, чтобы понять суть возникшей проблемы. Аналогично, программисту часто бывает необходимо увидеть изменения, происшедшие в программе с течением времени.
comm — построчное сравнение двух сортированных файлов
Программа comm сравнивает два текстовых файла, показывая, какие строки в них уникальные, а какие — одинаковые. Для демонстрации создадим с помощью cat два почти идентичных файла: