Форум проекта PuppyRus Linux

Разработки проекта PuppyRus => Программирование и компиляция => Тема начата: Zloy_T от 24 Май 2009, 08:32:07

Название: GNU и UNIX команды. Текстовые потоки и фильтры
Отправлено: Zloy_T от 24 Май 2009, 08:32:07
Фильтрация текста - это процесс преобразований над входным потоком текста до того как он будет выдан в выходной поток. Хотя как входной, так и выходной поток могут поступать из файла, в системах Linux и UNIX фильтрация преимущественно осуществляется через конвейер команд, когда вывод одной команды связывается или перенаправляется на ввод следующей команды. Cейчас давайте взглянем на конвейер и простое перенаправление вывода с помощью операторов | и >.

Конвейер с помощью |

Вспомним из предыдущего раздела, что интерпретатор оперирует с тремя стандартными потоками ввода/вывода:
stdin это стандартный поток ввода, через который поступает ввод командам.
stdout это стандратный выходной поток, через который команды выводят свой выход.
stderr это стандартный поток ошибок, через который выводятся ошибки в командах.

До сих пор, в этом руководстве, ввод представлял собой параметры, которые мы передавали командам, а вывод отображался на терминал. Многие команды обработки текста (фильтры) могут принимать входной поток, как из стандартного ввода, так и из файла. Чтобы использовать выход команды command1, как входной фильтр command2 вы должны соединить команды с помощью операции конвейерезации (|), как показано в Листинге 20.

Листинг 20. Связывание выхода command 1 со входом command2

Код
command1 | command2

У любой из команд могут быть опции или аргументы, как вы увидите далее в этом разделе. Вы можете также использовать | для перенаправления вывода command2 в этом конвейере на вход другой команде, command3. Конструируя длинные конвейеры из команд, каждая из которых выполняет свою задачу, можно понять философию выполнения задач в Linux и UNIX. Также иногда вы будете видеть знак дефиса (-) вместо имени файла в качестве аргумента команды, в том значении, что ввод будет поступать из stdin, а не из файла.

Перенаправление вывода с помощью >

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

В этой части руководства мы будем использовать небольшие файлы, поэтому давайте создадим каталог lpi103 и перейдем в него. Мы будем использовать > для перенаправления вывода echo в файл text1. Все это показано в Листинге 21. Заметим, что вывод не отображается на терминале, потому что он был перенаправлен в файл.

Листинг 21. Перенаправление вывода command 1 в файл


Код
[ian@echidna ian]$ mkdir lpi103
[ian@echidna ian]$ cd lpi103
[ian@echidna lpi103]$ echo -e "1 apple\n2 pear\n3 banana">text1

Теперь, имея в арсенале простые инструменты для создания конвейера и перенаправления, взглянем на наиболее распространенные утилиты обработки текста в UNIX и Linux. Этот раздел описывает некоторые простые возможности; чтобы узнать больше, смотрите соответсвующие страницы руководств по этим командам.

Cat, tac, od и split

Вы создали файл test1, теперь вы захотите посмотреть его содержимое. Используйте команду cat (сокращение от catenate),чтобы отобразить содержимое файла на stdout. Листинг 22 проверяет содержимое файла, созданного выше.

Листинг 22. Вывод содержимого файла с помощью cat

Код
[ian@echidna lpi103]$ cat text1
1 apple
2 pear
3 banana

Команда cat принимает ввод из stdin, если вы не определите имя файла (или если напишите - как имя файла). Давайте используем эту возможность, а также перенаправление вывода, чтобы создать еще один текстовый файл как в Листинге 23.

Листинг 23. Создание текстового файла с помощью cat

Код
[ian@echidna lpi103]$ cat>text2
9 plum
3 banana
10 apple

В Листинге 23 cat продолжает читать из stdin до конца файла. Используйте комбинацию Ctrl-d (нажмите Ctrl, а затем нажмите d), чтобы послать сигнал конца файла. Такая же комбинация клавиш используется для выхода из bash. Заметим, что клавиша tab позволяет выровнить в столбец имена фруктов.

Случайно вам захотелось отобразить файл в обратном порядке. Разумеется, для этого тоже существует текстовый фильтр под названием tac (перестановка букв в cat). Листинг 24 отображает как новый файл text2, так и старый text1 в обратном порядке. Заметим, как просто соединились два файла.

Листинг 24. Реверсивное отображение с помощью tac

Код
[ian@echidna lpi103]$ tac text2 text1
10 apple
3 banana
9 plum
3 banana
2 pear
1 apple

Теперь положим, что вы отобразили два текстовых файла с помощью cat и tac и заметили разницу в выравнивании. Чтобы понять, почему это так, необходимо взглянуть на управляющие символы в файле. Так как они не имеют графического представления, то нам необходимо создать дамп файла в формате, который позволит вам найти и интерпретировать эти особые символы. Пакет текстовых утилит GNU включает команду od (или OctalDump) специально для этой цели.

У команды od есть несколько опций, как например -A для управления основанием смещений файла и -t для управления формой отображения содержимого файла. Основание может быть o, (восьмиричное - по умолчанию), d (десятичное), x (шестнадцатиричное) или n (смещения не отображаются). Вы можете отобразить файл в виде восьмиричном, шестнадцатиричном, десятичном, с плавающей точкой, ASCII с escape последовательностями или именоваными символами (nl для новой строки, ht для горизонтальной табуляции и так далее). В Листинге 25 представлены некоторые доступные форматы дампа файла text2.

Листинг 25. Дамп файлов с помощью od

Код
[ian@echidna lpi103]$ od text2
0000000 004471 066160 066565 031412 061011 067141 067141 005141
0000020 030061 060411 070160 062554 000012
0000031
[ian@echidna lpi103]$ od -A d -t c text2
0000000 9 \t p l u m \n 3 \t b a n a n a \n
0000016 1 0 \t a p p l e \n
0000025
[ian@echidna lpi103]$ od -A n -t a text2
9 ht p l u m nl 3 ht b a n a n a nl
1 0 ht a p p l e nl

Замечение:
Опция -A утилиты cat предоставляет альтернативный способ увидеть, где завершаются строки и символы табуляции. Для получения подробной информации смотрите man-страницы.
Если у вас есть знания об устройстве ЭВМ, то возможно вас заинетересует утилита hexdump, которая являюется частью другого набора утилит. Она здесь не рассматривается, поэтому обратитесь к man-страницам.

Наши тестовые файлы очень малы, но иногда требуется разбить большие файлы на несколько небольших. Например, вы хотите разбить большой файл на куски объемом с CD, чтобы их записать да CD и отправить по почте кому-нибудь, кто может создать для вас DVD. Команда split сделает это таким образом, что cat можно будет использовать для простого воссоздания файла. По умолчанию, файлы на выходе команды split имеют префикс 'x' в имени, за которым следует суффикс 'aa', 'ab', 'ac', ..., 'ba', 'bb' и так далее. Существуют опции, позволяющие изменять эти умолчания. Вы также можете управлять размером выходных файлов, как в строках, так и в байтах. В Листинге 26 происходит разделение двух текстовых файлов с разными префиксами в именах выходных файлов. Мы разделим text1 на файлы, содержащие не более двух строк, а text2 на файлы размером не более 18 байт. Затем мы используем cat для отображения различных частей, а также для отображения всего файла, используя подстановку, которая рассмотрена в разделе шаблоны и подстановки позже в этом руководстве.

Листинг 26. Разделение и воссоединение с помощью split и cat


Код
[ian@echidna lpi103]$ split -l 2 text1
[ian@echidna lpi103]$ split -b 18 text2 y
[ian@echidna lpi103]$ cat yaa
9 plum
3 banana
10[ian@echidna lpi103]$ cat yab
apple
[ian@echidna lpi103]$ cat y*
9 plum
3 banana
10 apple

Заметим, что получившийся файл yab не содержит символ новой строки, поэтому наше приглашение было смещено, когда мы использовали cat для его отображения.

Wc, head и tail

Cat и tac отображают файл целиком. Для маленьких файлов, с которыми имеем дело мы, это нормально, но предположим, что у вас большой файл. Для начала вы можете использовать команду wc (Word Count), чтобы посмотреть размер файла. Команда wc отображает число строк, слов и байт в файле. Вы также можете узнать число байт с помощью ls -l. Листинг 27 показывает длинный формат списка каталогов для двух файлов, а также вывод команды wc.

Листинг 27. Использование wc с текстовыми файлами

Код
[ian@echidna lpi103]$ ls -l text*
-rw-rw-r-- 1 ian ian 24 Sep 23 12:27 text1
-rw-rw-r-- 1 ian ian 25 Sep 23 13:39 text2
[ian@echidna lpi103]$ wc text*
3 6 24 text1
3 6 25 text2
6 12 49 total

Различные опции позволяют вам контролировать вывод команды wc илиотображать другую информацию, как например максимальная длина строки. Более подробно написано в man-страницах.

Две команды позволяют вам отобразить как начало (head) так и конец файла (tail). Это команды соответственно head и tail. Их можно использовать как фильтры, или же они могут принимать имя файла как аргумент. По умолчанию они отображают первые (или последние) 10 строк файла или потока.В Листинге 28 использована команда dmesg для отображения сообщений о загрузке совместно с wc, tail и head чтобы узнать, что всего имеется 177 сообщений, затем отображаются последние 10 строк, и, наконец, отображаются шесть сообщений, начиная с 15 от конца. Некоторые строки были обрезаны в этом выводе (об этом свидетельствует ...).

Листинг 28. Использование wc, head и tail для отображения загрузочных сообщений

Код
[ian@echidna lpi103]$
[ian@echidna lpi103]$ dmesg | wc
177 1164 8366
[ian@echidna lpi103]$ dmesg | tail
i810: Intel ICH2 found at IO 0x1880 and 0x1c00, MEM 0x0000 and ...
i810_audio: Audio Controller supports 6 channels.
i810_audio: Defaulting to base 2 channel mode.
i810_audio: Resetting connection 0
ac97_codec: AC97 Audio codec, id: ADS98 (Unknown)
i810_audio: AC'97 codec 0 Unable to map surround DAC's (or ...
i810_audio: setting clocking to 41319
Attached scsi CD-ROM sr0 at scsi0, channel 0, id 0, lun 0
sr0: scsi3-mmc drive: 0x/32x writer cd/rw xa/form2 cdda tray
Uniform CD-ROM driver Revision: 3.12
[ian@echidna lpi103]$ dmesg | tail -n15 | head -n 6
agpgart: Maximum main memory to use for agp memory: 941M
agpgart: Detected Intel i845 chipset
agpgart: AGP aperture is 64M @ 0xf4000000
Intel 810 + AC97 Audio, version 0.24, 13:01:43 Dec 18 2003
PCI: Setting latency timer of device 00:1f.5 to 64
i810: Intel ICH2 found at IO 0x1880 and 0x1c00, MEM 0x0000 and ...

Другим популярным использованием tail является слежение за файлом с помощью опции -f, обычно построчно. Это может полезным, если у вас есть фоновый процесс, который генерирует вывод в файл, и вы хотите проверить, что он сделал. В этом режиме tail будет работать, пока вы не прекратите его работу (с помощью Ctrl-c), отображая строки по мере того, как они будут поступать в файл.

Expand, unexpand и tr

Когда мы создали файлы text1 и text2, то использовали в text2 символы табуляции. Иногда требуется заменить символы табуляции на другие символы и наоборот. Команды expand и unexpand этим и занимаются. Опция -t в обеих командах позволяет установить шаг табуляции. Таким образом, каждый символ табуляции заменяется на этот шаг. В Листинге 29 показано, как заменить символы табуляции в text2 на пробелы, а также странная последовательность expand и unexpand которая переупорядочивает текст в text2.

Листинг 29. Использование expand и unexpand

Код
[ian@echidna lpi103]$ expand -t 1 text2
9 plum
3 banana
10 apple
[ian@echidna lpi103]$ expand -t8 text2|unexpand -a -t2|expand -t3
9 plum
3 banana
10 apple

К сожалению, вы не можете использовать unexpand, чтобы заменить пробелы в text1 на символы табуляции, так как unexpand необходимо по крайней мере два пробела для преобразования их в символ табуляции. Однако вы можете использовать команду tr которая переводит символы из одного набора (set1) в соответствующие символы другого набора(set2). В Листинге 30 показано, как использовать tr, чтобы преобразовать пробелы в символы табуляции. Так как tr это фильтр, то входные данные для него вы генерируете с помощью команды cat.Этот пример также иллюстрирует применение - для обозначения стандартного ввода в cat.

Листинг 30. Использование expand и unexpand

Код
[ian@echidna lpi103]$ cat text1 |tr ' ' '\t'|cat - text2
1 apple
2 pear
3 banana
9 plum
3 banana
10 apple

Если вы не уверены в том, что происходит в последних двух примерах, то наберите od, чтобы проверить каждую стадию конвейера; например
Код
cat text1 |tr ' ' '\t' | od -tc 


Pr, nl и fmt

Команда pr используется для форматирования файлов перед печатью. Заголовок по умолчанию включает имя файла и даты и время создания файла, а также номер страницы и двух пустых строк сносок. Когда выходной поток создается из нескольких файлов или из входного потока, то текущая дата и время появляются вместо имени файла и даты создания. Вы можете напечатать файлы параллельно в столбцах и управлять с помощью опций различными возможностями форматирования. Как обычно, смотрите man-страницы, чтобы узнать подробности.

Команда nl нумерует строки, что может быть полезно при печати файлов. Вы также можете нумеровать строки с помощью опции -n команды cat. На Листинге 31 показано как напечатать наш файл text 1, а затем как пронумеровать text2 и напечатать его параллельно с text1.

Название: GNU и UNIX команды. Текстовые потоки и фильтры. Часть 2
Отправлено: Zloy_T от 24 Май 2009, 08:32:54
Листинг 31. Нумерация и форматирование для печати

Код
[ian@echidna lpi103]$ pr text1 | head
2005-09-23 12:27 text1 Page 1
1 apple
2 pear
3 banana
[ian@echidna lpi103]$ nl text2 | pr -m - text1 | head
2005-09-26 11:48 Page 1
1 9 plum 1 apple
2 3 banana 2 pear
3 10 apple 3 banana

Другой полезной командой форматирования текста является fmt, которая форматирует текст так, что он подходит по определенным размерам. Вы можете соединить несколько коротких строк, а также разделить на несколько строк. В Листинге 32 мы создаем файл text3 с одной большой строкой текста, используя возможности истории с помощью !#:*, чтобы не печатать наше предложение четыре раза. Мы также создадим файл text4, содержащий по одному слову на строке. Затем мы будем использовать cat, чтобы отобразить их в неформатированном виде, включая символ '$' для обозначения конца строк. Наконец, мы используем fmt для форматирования их с максимальной шириной строкой в 60 символов. Снова, обращайтесь к man-страницам за более подробной информацией.

Листинг 32. Форматирование по максимальной длине строки

Код
[ian@echidna lpi103]$ echo "This is a sentence. " !#:* !#:1-$>text3
echo "This is a sentence. " "This is a sentence. " "This is a sentenc
e. " "This is a sentence. ">text3
[ian@echidna lpi103]$ echo -e "This\nis\nanother\nsentence.">text4
[ian@echidna lpi103]$ cat -et text3 text4
This is a sentence. This is a sentence. This is a sentence. This i
s a sentence. $
This$
is$
another$
sentence.$
[ian@echidna lpi103]$ fmt -w 60 text3 text4
This is a sentence. This is a sentence. This is a
sentence. This is a sentence.
This is another sentence.

Sort и uniq

Команда sort сортирует ввод, согласно схеме локали (LC_COLLATE) в системе. Команда sort также может соединять файлы и проверять, является ли файл отсортированным или нет.

Листинг 33 иллюстрирует применение команды sort для сортировки двух файлов, после того как мы преобразовали пробелы в символы табуляции в text1. Так как порядок сортировки происходит по символам, то результаты могут вас удивить. К счастью команда sort может сортировать как по числовым значениям, так и по символам. Порядок сортировки можно определить как для целой записи, так для каждого поля. Пока вы не укажите другой разделитель, поля будут разделяться пробелами и табуляторами. Второй пример в Листинге 33 показывает сортировку первого поля по цифрам, а второго поля по буквам с помощью схемы упорядочивания (в алфавитном порядке). Он также иллюстрирует применение опции -u для уничтожения любых дублируемых строк.

Листинг 33. Сортировка по символам и числам

Код
[ian@echidna lpi103]$ cat text1 | tr ' ' '\t' | sort - text2
10 apple
1 apple
2 pear
3 banana
3 banana
9 plum
[ian@echidna lpi103]$ cat text1|tr ' ' '\t'|sort -u -k1n -k2 - text2
1 apple
2 pear
3 banana
9 plum
10 apple

Заметим, что у нас все еще есть две строчки, содержащие фрукт "apple". Другая команда uniq дает нам дополнительный контроль над выявлением дублирующих строк. Команда uniq обычно работает с отсортированными файлами, но удаляет последовательные одинаковые строки из любого файла, отсортированного или нет. Команда uniq также может игнорировать некоторые поля. В Листинге 34 показана сортировка двух файлов по второму полю (имени фрукта), а затем уничтожение идентичных по второму полю строк.

Листинг 34. Использование uniq

Код
[ian@echidna lpi103]$ cat text1|tr ' ' '\t'|sort -k2 - text2|uniq -f1
10 apple
3 banana
2 pear
9 plum

Сортировка производилась согласно схеме упорядочивания, поэтому uniq выдало результат "10 apple", а не "1 apple". Попытайтесь добавить сортировку первого поля по числам, чтобы увидеть изменения.

Cut, paste и join

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

Листинг 35. Использование cut

Код
[ian@echidna lpi103]$ cut -f1-2 --output-delimiter=' ' text2
9 plum
3 banana
10 apple

Команда paste вставляет строки из двух или более файлов параллельно, подобно тому, как команда pr объединяет два файла с помощью опции -m. Листинг 36 демонстрирует результат вставки двух текстовых файлов.

Листинг 36. Вставка файлов

Код
[ian@echidna lpi103]$ paste text1 text2
1 apple 9 plum
2 pear 3 banana
3 banana 10 apple

Эти примеры показывают простую вставку, но paste может вставлять данные из одного или нескольких файлов различными способами. За подробностями обращайтесь к man-страницам.

Последняя команда манипулирования с полями это join, которая объединяет файлы на основе соответствия полей. Эти файлы должны быть отсортированы по объединяемому полю. Так как text2 не отсортирован по числовому порядку, мы можем отсортировать его, а затем объединить две строки, которые имеют одинаковое поле (а данном случае 3). Давайте также создадим новый файл, text5, отсортировав text 1 по второму полю (имени фрукта), а затем заменив пробелы на символы табуляции. Если мы затем отсортируем text2 и объединим его с text 5 по второму полю, то получим два совпадения (яблоко и банан). Листинг 37 иллюстрирует эти примеры.

Листинг 37. Объединение файлов по полям

Код
[ian@echidna lpi103]$ sort -n text2|join -1 1 -2 1 text1 -
3 banana banana
[ian@echidna lpi103]$ sort -k2 text1|tr ' ' '\t'>text5
[ian@echidna lpi103]$ sort -k2 text2 | join -1 2 -2 2 text5 -
apple 1 10
banana 3 3

Поле, используемое для объединения, указывается отдельно для каждого файла. Вы можете, например, объединить файл по полю 3 с файлом по полю 10.

Sed

Sed это streameditor (потоковый редактор).Sed чрезвычайно мощный инструмент, а задачи, которые можно выполнить с его помощью, ограничены лишь вашим воображением. Это небольшое введение должно пробудить у вас интерес к sed, но оно не является полным или расширенным.

Как и другие команды, которые мы рассмотрели, sed может работать как фильтр или получать ввод из файла. Вывод осуществляется на стандартный поток вывода. Sed загружает строки из ввода в пространство шаблонов, применяет команды редактирования sed к содержимому пространства шаблонов, а затем осуществляет на стандартный вывод пространства шаблонов. Sed может скомпоновать несколько строк в пространстве шаблонов, и может результат записать в файл, записать только частичный вывод, или же вообще ничего не записывать.

Sed использует синтаксис регулярных выражений (смотри Поиск с помощью регулярных выражений далее в этом руководстве) для поиска и избирательной замены текста в пространстве шаблонов, а также выбора тех строк, над которыми необходимо провести набор команд редактирования. Специальный буфер предоставляет временное хранилище для текста. Буфер может заменить пространство шаблонов, может быть добавлен к пространству шаблонов или же вести обмен с пространством шаблонов. Sed имеет ограниченный набор команд, но при использованию синтаксиса регулярных выражений и буфера может предоставлять потрясающие возможности. Набор команд sed обычно называется sed-сценарием.

В Листинге 38 представлено три простых sed-сценария. В первом мы используем команду s (замещения) буквы 'а' в нижнем регистре на верхний в каждой строке. Этот пример замещает только первые вхождения 'a', поэтому во втором примере мы добавили флаг 'g' (от глобальный) для замещения всех вхождений буквы. В третьем сценарии мы рассматриваем команду d (удалить) для удаления строки. В нашем примере мы используем адрес второй строки, чтобы показать, что только ее необходимо удалить. Мы разделяем команды точкой с запятой (;) а затем используем глобальное замещение, которое мы использовали во втором сценарии для замены 'a' на 'A'.

Листинг 38. Начало работы с sed-сценариями

Код
[ian@echidna lpi103]$ sed 's/a/A/' text1
1 Apple
2 peAr
3 bAnana
[ian@echidna lpi103]$ sed 's/a/A/g' text1
1 Apple
2 peAr
3 bAnAnA
[ian@echidna lpi103]$ sed '2d;$s/a/A/g' text1
1 apple
3 bAnAnA

В дополнение работе с одиночными строками, sed может работать с группой строк. Начало и конец диапазона разделяется запятой (,) и это может быть, как и номер строки, каретка (^), означающая начало файла, так и знак доллара ($), означающий конец файла. Зная адрес или диапазон адресов, вы можете сгруппировать несколько команд и заключить их в фигурные скобки ({ и }) так, что эти команды будут выполнены только на определенном диапазоне строк. Листинг 39 иллюстрирует два способа глобальной подстановки, применимой только к двум последним строкам файла. Он также иллюстрирует применение опции -e для исполнения команд в пространстве шаблонов. При использовании круглых скобок команды необходимо разделять запятыми.

Листинг 39. Sed с использованием адресации

Код
[ian@echidna lpi103]$ sed -e '2,${' -e 's/a/A/g' -e '}' text1
1 apple
2 peAr
3 bAnAnA
[ian@echidna lpi103]$ sed -e '/pear/,/bana/{' -e 's/a/A/g' -e '}' text1
1 apple
2 peAr
3 bAnAnA

Sed-сценарии могут также храниться в файлах. На самом деле вы захотите так сделать для часто используемых сценариев. Помните, раньше мы использовали команду tr для замены пробелов в text1 на символы табуляции. Давайте теперь сделаем это с помощью sed-сценария, хранящегося в файле. Мы будем использовать команду echo для создания файла. Результаты представлены в Листинге 40.

Листинг 40. Использование sed-сценария

Код
[ian@echidna lpi103]$ echo -e "s/ /\t/g">sedtab
[ian@echidna lpi103]$ cat sedtab
s/ / /g
[ian@echidna lpi103]$ sed -f sedtab text1
1 apple
2 pear
3 banana

Существует множество таких удобных сценариев как в Листинге 40.

Наш последний пример sed использует команду = для вывода номеров строк, а затем фильтрации вывода опять через sed для имитации эффекта команды nl для нумерации строк. Листинг 41 использует = для вывода номеров строк, а затем использует команду N для помещения каждой второй строки в пространство шаблонов в продолжение первой, и наконец удаляет символ новой строки (\n) между двумя строками в пространстве шаблонов.

Листинг 41. Нумерация строк в sed

Код
[ian@echidna lpi103]$ sed '=' text2
1
9 plum
2
3 banana
3
10 apple
[ian@echidna lpi103]$ sed '=' text2|sed 'N;s/\n//'
19 plum
23 banana
310 apple

Не совсем то, что мы хотели! Мы хотели, чтобы нумерация была выровнена по столбцу, а также, чтобы номера и строки файла отделяли несколько пробелов. В Листинге 42 мы вводим несколько строк команд (заметим второе приглашение >). Изучите пример и посмотрите объяснение ниже.

Листинг 42. Нумерация строк с sed - второй подход

Код
[ian@echidna lpi103]$ cat text1 text2 text1 text2>text6
[ian@echidna lpi103]$ ht=$(echo -en "\t")
[ian@echidna lpi103]$ sed '=' text6|sed "N
> s/^/ /
> s/^.*\(......\)\n/\1$ht/"
1 1 apple
2 2 pear
3 3 banana
4 9 plum
5 3 banana
6 10 apple
7 1 apple
8 2 pear
9 3 banana
10 9 plum
11 3 banana
12 10 apple

Шаги, которые мы предприняли:
Мы использовали cat, чтобы создать файл из 12 строк с помощью двух копий text1 и text2. Нет никакого интереса в форматировании чисел, если все они одного порядка.
Bash использует клавишу tab для автозавершения команды, поэтому полезно иметь уже заготовленный символ табуляции, чтобы использовать его, когда он действительно понадобиться. Мы используем команду echo, чтобы вывести и сохранить его в shell переменной 'ht'.
Мы создаем поток, содержащий номера строк и данные как мы делали до этого и фильтруем его через вторую копию sed.
Мы вторые строки вместе с первыми в пространство шаблонов
Мы предваряем нашу строку с нумерацией в начале пространства шаблонов (обозначаемого ^) шестью пробелами.
Затем замещаем строку с пробелами и символом новой строки символом табуляции. Заметим, что левая часть команды 's' использует '\(' и '\)' для обозначения символов, которые мы хотим использовать в правой части. В правой части мы ссылаемся на первое такое найденное множество (и только такое в данном примере) как \1. Заметим, что наша команда находится между двойных кавычек ("), так что данная подстановка будет определена для $ht.

Последняя версия (версия 4) sed содержит документацию в формате info и включает много превосходных примеров. Их нет в старой версии 3.02. GNU sed примет команду sed --version и отобразит свою версию.

Взято с ibm developerworks

http://system-administrators.info/?p=736 (http://system-administrators.info/?p=736)