Потоки в *NIX системах
Своим происхождением UNIX® обязан простой обработке текстов, и среда его командной строки остается одним из самых мощных доступных инструментов. Комбинируя ряд простых команд, обеспечивающих сложные преобразования текста, вы можете создать при помощи доступных в UNIX средств почти любой нужный вам инструмент обработки текста.
Потоки стандартного ввода/вывода
Прежде чем начать управлять текстом при помощи текстовых Unix утилит, сначала потребуется узнать, как получить какого бы то ни было текста.Каждая программа UNIX имеет три стандартных потока: ввод, вывод, и сообщение об ошибке (или stdin, stdout и stderr которые представлены в каждой программе на C).Когда вы перенаправляете вывод программы в файл при помощи оператора > в оболочке, вы посылаете поток ее стандартного вывода (stdout) в файл. Например: ls > this-dir посылает вывод ls в файл с именемthis-dir.Когда вы перенаправляете ввод программы из файла при помощи оператора < в оболочке, вы извлекаете содержимое файла в поток ее стандартного ввода (stdin). Например: sort < this-dirсчитывает содержимое файла с именем this-dirи предоставляет его как ввод команде sort.Другой общий оператор для перенаправления стандартных потоков - это оператор | (pipe), который связывает поток стандартного вывода программы слева с потоком стандартного ввода программы справа. Например: ls | sortделает то же, что и предыдущие два примера, не требуя временного файла; вывод lsпроходит напрямую через команду sort.Поток стандартных сообщений об ошибке (stderr) не представлен ни в одном из примеров. Как и поток стандартного вывода, stderr может быть перенаправлен в файл или другую программу, но вам потребуется сообщить оболочке, что вы хотите работать с stderr вместо stdout.Перенаправляйте поток стандартных сообщений об ошибке в файл при помощи оператора 2>. Чаще всего вы это будете видеть, работая с командами, выводящими содержательные сообщения об ошибке, такими как инструмент make, используемый для сборки программ под UNIX: make 2> build-errors.Эта команда запускает make и посылает любые сообщения об ошибках в файл build-errors. Подобным образом вы бы использовали 2|, чтобы перенаправить stderr в другую программу.Если вас интересуют не приукрашенные детали, у других потоков также есть номера, хотя они почти никогда не используются (0 - это стандартный ввод, а 1 - стандартный вывод), за исключением одного на удивление обыкновенным оператором. В примере, приведенном в Листинге 1, оператор 2>&1 привязывает поток стандартных сообщений об ошибке к потоку стандартного вывода. В комбинации с оператором > вы получите stderr и stdout в одном и том же файле.
Листинг 1. Как привязать поток стандартных сообщений об ошибке к потоку стандартного вывода
make > build-output 2>&1
Есть две стандартные команды UNIX, которые часто используют для порождения некоторого текстового вывода:catиecho.Командаcatсчитывает каждый из файлов, указанных в ее аргументах, и выводит содержимое файлов в stdout. Командаechoвыводит в stdout свои аргументы. Вы будете часто их видеть в качестве части более сложной командной pipe-строки (см. Листинг 2).
cat file1 file2 ... filen
echo arguments...Но что, если вы хотите получить только первую часть файла, или последнюю? Есть два вариантаcatпод названиями head и tail (см. Листинг 3), которые сделают то, что вы хотите, выводя первые или последние десять строк, соответственно (для обеих команд вы можете указать другое количество строк при помощи опции-n).
head file1 file2 ... filenhead file1 file2 ... filenУ командыtailесть другая удобная опция-f(англ. follow, сопровождать). Она сообщаетtailпечатать последние десять строк указанного файла, но, вместо того, чтобы завершаться, она ждет, что в файле появится больше текста, и печатает его, как только он появляется. Это можно использовать, чтобы сопровождать вывод в журнал ошибок, к примеру, чтобы увидеть, какие ошибки появляются в момент, когда они записываются в журнал.
Командаtrпозволяет вам заменять символы из одного набора в соответствующие символы другого. Рассмотрим пример (Листинг 4).
chrish@dhcp3 [199]$ echo "a test" | tr t p
a pesp
chrish@dhcp3 [200]$ echo "a test" | tr aest 1234
1 4234chrish@dhcp3 [201]$ echo "a test" | tr -d t
a eschrish@dhcp3 [202]$ echo "a test" | tr '[:lower:]' '[:upper:]'
A TESTПервый и второй примеры достаточно просты: один символ заменяется другим. Третий пример, с опцией
-d(англ. delete, удаление), полностью удаляет указанные символы из вывода. Это часто используется для удаления символов возврата каретки из текстовых файлов DOS, чтобы превратить их в текстовые файлы UNIX (см. Листинг 6). Наконец, в последнем примере применяются классы символов (эти имена в [: :]), чтобы конвертировать все буквы в нижнем регистре в буквы в верхнем регистре. Классы символов стандарта интерфейса переносимой операционной системы Portable Operating System Interface (стандарта POSIX) включают в себя:
alnum: алфавитно-цифровые символы (alphanumeric characters)alpha: алфавитные символы (alphabetic characters)cntrl: контрольные (непечатные) символы (control (non-printing) characters)digit: цифровые символы (numeric characters)graph: графические символы (graphic characters)lower: алфавитные символы в нижнем регистре (lower-case alphabetic characters)punct: символы пунктуации (punctuation characters)space: символы пробела (whitespace characters)upper: символы в верхнем регистре (upper-case characters)xdigit: шестнадцатиричные символы (hexadecimal characters)
tr -d '\r' output_unix_file.txt
Возможности односимвольной замены (или удаления), предоставляемые командойtr, велики в особых случаях, но не очень гибки. Что, если вам требуется заменить одно слово другим, или ряд пробелов и символов табуляции одним пробелом?К счастью, в вашем распоряжении командаsed(англ. Stream EDitor, редактор потока), которая обеспечивает мощный поиск совпадений и замену при помощи регулярных выражений. Регулярные выражения - это сложные указания шаблонов, образуемые при помощи строительных блоков, которые в итоге выглядят более всего похожими на помехи в модеме по мере того, как шаблон усложняется. Детальное руководство по регулярным выражениям - это материал для другой статьи, а здесь вы кратко ознакомитесь с некоторыми удобными для использования вsedшаблонами.Основной формат командыsedпоказан в Листинге 7. Шаблон (pattern) - это регулярное выражение, используемое для поиска совпадений во входном потоке (обычно либо перенаправленном из другой программы, либо из текстового файла), а замена (replacement) - это текст, который следует вставить вместо текста, совпавшего с шаблоном. Флаги (flags) - это одиночные символы, контролирующие поведение этой подстановки. Самый часто используемый флаг - этоg(применить замену ко всем непересекающимся экземплярам, которые совпадают с шаблоном, вместо того, чтобы применить ее только к первому совпадению).Шаблон и замена могут быть практически чем угодно, и они не должны быть в одно-однозначном соответствии, как это происходит с командойtr.
sed -e s/pattern/replacement/flagsСамый простой шаблон - это просто строка из одного или нескольких символов. В Листинге 8, например, одно слово заменяется другим.
#echo "Replace one word" | sed -e s/one/another/
Replace another wordВы можете поставить один или несколько символов в квадратные скобки, чтобы создать множество; любой символ из этого множества совпадет. Заменим все гласные на символы подчеркивания (см. Листинг 9).
#echo "This is a test" | sed -e s/[aeiouy]/_/g
Th_s _s _ t_stОбратите внимание на использование флага
g, чтобы применить шаблон/замену к каждому совпадению вместо просто первого.Командаsedтакже учитывает именованные классы символов, которые поддерживает командаtr; они определены в POSIX, но здесь применяется другой синтаксис. Листинг 10 показывает вам, как заменять любой пробел (знаки табуляции, пробелы и т.д.):
Листинг 10. Поиск совпадений элемента именованного класса символов
#echo -e 'hello\tthere'
hello there
#echo -e 'hello\tthere' | sed -e 's/[[:space:]]/, /'
hello, thereФлаг-eкомандыechoуказывает ей расширять escaped-символы стиля C; в данном случае он превратит\tв знак табуляции для вас.Вы также можете использовать символ "." (точка) для поиска соответствий любого одиночного символа. Это действительно удобно, когда вы работаете с данными, которые не характеризуются разнообразием, или с данными, в которых встречаются специальные символы, которые будет сложно сделать escaped-символами. Например, я часто применяю
., когда я ищу совпадения кавычек, поэтому мне не требуется делать кавычки escaped-символами в оболочке. В Листинге 11 показан случай, когда, применяя этот шаблон, пользователь, возможно, создал новое регулярное выражение.
#echo "This is a test" | sed -e s/./_/g
______________
Теперь, когда самое основное вы уже увидели, рассмотрим несколько дополнительных модификаторов шаблонов; теперь вы станете также использовать опцию-Eвместо-e, чтобы пользоваться усовершенствованными регулярными выражениями. Символ?обозначает поиск нуля или одного соответствия предшествующему элементу шаблона; символ*означает поиск нуля или более соответствий предшествующему ему элементу. Символ+обозначает поиск одного или нескольких соответствий предшествующему элементу. Символ^соответствует началу строки, а$- концу. Это можно увидеть в действии, как показано в Листинге 12.
helloooo_
hell_
hell_
Если вы поставите элементы шаблона в круглые скобки, то сможете использовать найденные совпадения в строке замены. Они называются группами; благодаря ним поиск регулярных выражений обретает высокую эффективность, но читаемость выражения в существенной степени затрудняется. Например, ищется один или несколько символов l (эль), за которыми следуют ноль или несколько символов o. Они заменяются содержимым второй группы, за которым следует первая, то есть, на самом деле, они меняются местами. Обратите внимание, что на группы следует указывать при помощи бэкслеша с номером группы в шаблоне.
- Войдите на сайт для отправки комментариев
примеры использования потоков в жизни
почистить конфиг от комментариев
cat /etc/exim/exim.conf|grep -vi "^[ \t#]*$"|grep -vi "^[ \t#]*#.*$"
тут нашел как всегда не случайно :)
.