Добавить в цитаты Настройки чтения

Страница 66 из 113



gdm:x:106:114:Gnome Display Manager:/var/lib/gdm:/bin/false

hplip:x:104:7:HPLIP system user,,,:/var/run/hplip:/bin/false

klog:x:103:104::/home/klog:/bin/false

messagebus:x:108:119::/var/run/dbus:/bin/false

polkituser:x:110:122:PolicyKit,,,:/var/run/PolicyKit:/bin/false

pulse:x:107:116:PulseAudio daemon,,,:/var/run/pulse:/bin/false

Определив двоеточие как разделитель полей, мы смогли выполнить сортировку по седьмому полю.

uniq — выявление или удаление повторяющихся строк

В сравнении с sort программа uniq более легковесна. Она решает, казалось бы, тривиальную задачу. Когда ей передается сортированный файл (в том числе и стандартный ввод), она удаляет повторяющиеся строки и выводит результат в стандартный вывод. Она часто используется в сочетании с sort для удаления повторяющихся строк.

ПРИМЕЧАНИЕ

Даже при том что uniq — инструмент, традиционный для Unix, который часто используется вместе с sort, GNU-версия sort поддерживает параметр -u, удаляющий повторяющиеся строки из сортированных результатов.

Давайте создадим текстовый файл для последующих экспериментов:

[[email protected]/* */ ~]$ cat > foo.txt

a

b

c

a

b

c

Не забудьте ввести CTRL+D, чтобы завершить ввод с клавиатуры. Если теперь применить uniq к нашему текстовому файлу, результат ничем не будет отличаться от оригинала; повторяющиеся записи никуда не исчезли:

[[email protected]/* */ ~]$ uniq foo.txt

a

b

c

a

b

c

Чтобы uniq действительно выполнила свою работу, исходные данные нужно сначала отсортировать:

[[email protected]/* */ ~]$ sort foo.txt | uniq

a

b

c

Это объясняется тем, что uniq удаляет повторяющиеся записи, только если они следуют друг за другом.

uniq имеет несколько параметров. Наиболее часто используемые из них перечислены в табл. 20.2.

В следующем примере используется параметр -c программы uniq для определения числа повторяющихся строк в исходном текстовом файле:

[[email protected]/* */ ~]$ sort foo.txt | uniq -c

      2 a

      2 b

      2 c

Таблица 20.2. Часто используемые параметры команды uniq

Параметр

Описание

-c

Вывести список повторяющихся строк, предваряя их числом найденных дубликатов

-d

Вывести только повторяющиеся, не уникальные строки

-f n

Пропустить n начальных полей в каждой строке. Деление на поля производится по пробельным символам, как в программе sort; однако, в отличие от sort, программа uniq не имеет параметра для настройки альтернативного разделителя полей

-i

Сравнивать строки без учета регистра символов

-s n

Пропустить n начальных символов в каждой строке

-u

Вывести только уникальные строки. Подразумевается по умолчанию

Нарезка и перетасовка текста

Далее мы обсудим три программы, которые используются для выделения колонок текста из файлов и их компоновки различными способами.

cut — удаление фрагментов из всех строк в файлах

Программа cut используется для извлечения фрагментов текста из строк и вывода их в стандартный вывод. Она может принимать имена файлов в аргументах или данные со стандартного ввода.

Определение фрагментов строк, подлежащих извлечению, реализовано не очень удобно, и для этой цели применяются параметры, перечисленные в табл. 20.3.

Таблица 20.3. Параметры команды cut для выбора фрагментов

Параметр

Описание

-c список_символов

Извлекает фрагмент строки, определяемый списком_символов. Список может включать один или несколько числовых диапазонов, разделенных запятыми

-f список_полей

Извлекает одно или несколько полей из строки, как определено аргументом список_символов. Список может включать одно или несколько полей или диапазонов полей, разделенных запятыми

-d символ_разделитель

В присутствии параметра -f в качестве разделителя полей используется символ_разделитель. По умолчанию поля должны отделяться друг от друга одним символом табуляции

--complement

Извлекает строку текста целиком, кроме фрагментов, определяемых параметром -c и/или -f

Как видите, программа cut не обладает особенной гибкостью. Она лучше всего подходит для извлечения фрагментов из текста, произведенного другими программами, а не человеком. Давайте вернемся к нашему файлу distros.txt и посмотрим, достаточно ли он «хорош» для программы cut. Если воспользоваться программой cat с парамет­ром -A, можно увидеть, отвечает ли файл требованию в отношении использования символа табуляции в качестве разделителя полей.



[[email protected]/* */ ~]$ cat -A distros.txt

SUSE^I10.2^I12/07/2006$

Fedora^I10^I11/25/2008$

SUSE^I11.0^I06/19/2008$

Ubuntu^I8.04^I04/24/2008$

Fedora^I8^I11/08/2007$

SUSE^I10.3^I10/04/2007$

Ubuntu^I6.10^I10/26/2006$

Fedora^I7^I05/31/2007$

Ubuntu^I7.10^I10/18/2007$

Ubuntu^I7.04^I04/19/2007$

SUSE^I10.1^I05/11/2006$

Fedora^I6^I10/24/2006$

Fedora^I9^I05/13/2008$

Ubuntu^I6.06^I06/01/2006$

Ubuntu^I8.10^I10/30/2008$

Fedora^I5^I03/20/2006$

Похоже, что все в порядке: пробелы отсутствуют и поля разделены единственными символами табуляции. Поскольку вместо пробелов в файле используются символы табуляции, можно воспользоваться параметром -f для извлечения поля:

[[email protected]/* */ ~]$ cut -f 3 distros.txt

12/07/2006

11/25/2008

06/19/2008

04/24/2008

11/08/2007

10/04/2007

10/26/2006

05/31/2007

10/18/2007

04/19/2007

05/11/2006

10/24/2006

05/13/2008

06/01/2006

10/30/2008

03/20/2006

Так как поля в файле distros.txt разделены символами табуляции, их удобнее извлекать с помощью cut именно как поля, а не как группы символов. Когда поля разделяются символами табуляции, маловероятно, что строки будут содержать одно и то же число символов, из-за чего определение позиций символов в строках становится сложной или неразрешимой задачей. В примере, приведенном выше, мы смогли извлечь поля с датами, которые, к нашей удаче, все имеют одинаковую длину, поэтому теперь мы можем показать, как выполняется извлечение групп символов, для чего попробуем извлечь год из каждой строки:

[[email protected]/* */ ~]$ cut -f 3 distros.txt | cut -c 7-10

2006

2008

2008

2008

2007

2007

2006

2007

2007

2007

2006

2006

2008

2006

2008

2006

Применив cut второй раз к нашему списку, мы смогли извлечь символы в позициях с 7-й по 10-ю, которые соответствуют году в поле с датой. Форма записи 7-10 — это пример определения диапазона. Полное описание особенностей определения диапазонов находится на странице справочного руководства (man) для команды cut.

При работе с полями определим разделитель, отличающийся от символа табуляции. Следующий пример извлекает первое поле из файла /etc/passwd:

[[email protected]/* */ ~]$ cut -d ':' -f 1 /etc/passwd | head

root

daemon

bin

sys

sync

games

man

lp

mail

news

С помощью параметра -d мы определили, что роль разделителя полей будет играть символ двоеточия.

замена символов табуляции

Наш файл distros.txt идеально отформатирован для извлечения полей с использованием cut. Но что, если нам понадобится обработать файл, вырезая фрагменты по символам, а не по полям? Для этого нам нужно заменить символы табуляции в файле соответствующим числом пробелов. К счастью, в GNU-пакете coreutils имеется инструмент для этого — программа expand. Она может принимать имена файлов в аргументах или данные со стандартного ввода и выводить измененный текст в стандартный вывод.