355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Уильям Шоттс » Командная строка Linux » Текст книги (страница 19)
Командная строка Linux
  • Текст добавлен: 12 апреля 2017, 12:30

Текст книги "Командная строка Linux"


Автор книги: Уильям Шоттс


Жанр:

   

ОС и Сети


сообщить о нарушении

Текущая страница: 19 (всего у книги 30 страниц)

Адрес

Описание

n

Номер строки, где n – положительное число

$

Последняя строка

/регулярное_выражение/

Строки, соответствующие простому регулярному выражению POSIX. Обратите внимание, что регулярное выражение должно ограничиваться символом слеша с обеих сторон. При желании можно использовать другие ограничительные символы, определив регулярное выражение в форме cрегулярное_выражениеc, где c  – альтернативный символ-ограничитель

адр1,адр2

Диапазон строк с номерами от адр1 по адр2 включительно. Каждый адрес может иметь любую форму из перечисленных выше

первая~шаг

Соответствует строке с номером первая и каждой последующей с указанным шагом. Например, адрес 1~2 соответствует всем строкам с нечетными номерами, а адрес 5~5 соответствует пятой строке и каждой пятой последующей

адр1,+n

Соответствует строке с адресом адр1 и следующим за ней n строкам

adr!

Соответствует всем строкам, кроме строки с адресом адр, где адрес может иметь любую форму из перечисленных выше

Рассмотрим разные способы адресации строк на примере файла distros.txt, созданного выше в этой главе. Сначала попробуем диапазоны номеров строк:

[me@linuxbox ~]$ sed -n '1,5p' distros.txt

SUSE             10.2    12/07/2006

Fedora           10      11/25/2008

SUSE             11.0    06/19/2008

Ubuntu           8.04    04/24/2008

Fedora           8       11/08/2007

В нашем примере мы вывели строки с 1 по 5. Для этого использовалась команда p, которая просто выводит строки, соответствующие адресам. Однако здесь нам пришлось добавить параметр -n (параметр подавления автоматического вывода), чтобы программа sed не выводила все строки, что она делает по умолчанию.

Далее попробуем задействовать регулярное выражение:

[me@linuxbox ~]$ sed -n '/SUSE/p' distros.txt

SUSE             10.2    12/07/2006

SUSE             11.0    06/19/2008

SUSE             10.3    10/04/2007

SUSE             10.1    05/11/2006

Включив регулярное выражение /SUSE/, заключенное в символы слеша, мы смогли выделить строки подобно тому, как это делает программа grep.

Наконец, попробуем применить оператор отрицания, добавив в адрес восклицательный знак (!):

[me@linuxbox ~]$ sed -n '/SUSE/!p' distros.txt

Fedora           10      11/25/2008

Ubuntu           8.04    04/24/2008

Fedora           8       11/08/2007

Ubuntu           6.10    10/26/2006

Fedora           7       05/31/2007

Ubuntu           7.10    10/18/2007

Ubuntu           7.04    04/19/2007

Fedora           6       10/24/2006

Fedora           9       05/13/2008

Ubuntu           6.06    06/01/2006

Ubuntu           8.10    10/30/2008

Fedora           5       03/20/2006

Здесь мы видим ожидаемый результат: все строки из файла, кроме совпавших с регулярным выражением.

Пока что мы познакомились лишь с двумя командами редактирования, поддерживаемыми программой sed, s и p. В табл. 20.8 приводится более полный список основных команд редактирования.

Таблица 20.8. Основные команды редактирования sed

Команда

Описание

=

Выводит номер текущей строки

a

Добавляет текст в конец текущей строки

d

Удаляет текущую строку

i

Вставляет текст в начало текущей строки

p

Выводит текущую строку. По умолчанию sed выводит все строки, но редактирует только соответствующие указанному адресу. Поведение по умолчанию можно отменить, передав параметр -n

q

Завершает sed без обработки остальных строк. Если параметр -n не указан, выводит текущую строку

Q

Завершает sed без обработки остальных строк

s/регулярное_выражение/строка_замены/

Замещает совпадение с регулярным выражением строкой замены. Строка замены может включать специальный символ &, обозначающий совпадение с регулярным выражением. Кроме того, строка замены может включать последовательности, с 1 по 9, обозначающие совпадения с соответствующими подвыражениями в регулярном выражении. Дополнительную информацию по этой теме можно найти в обсуждении обратных ссылок ниже. За символом слеша, закрывающим строку замены, может следовать необязательный флаг, определяющий дополнительные особенности поведения команды

y/множество1/множество2

Выполняет перекодирование, преобразуя символы из первого множества в символы второго множества. Имейте в виду, что, в отличие от программы tr, sed требует, чтобы оба множества были одинаковой длины

Команда s, вне всяких сомнений, используется намного чаще других команд редактирования. Далее мы рассмотрим только часть ее возможностей, выполняя редактирование нашего файла distros.txt. Мы уже говорили, что поле даты в distros.txt хранит информацию не в самом «дружественном» для компьютеров виде. Здесь даты записаны в формате ММ/ДД/ГГГГ, однако гораздо удобнее (для сортировки) было бы, если бы даты были записаны в формате ГГГГ-ММ-ДД. Замена представления дат вручную – довольно утомительное занятие и чревато ошибками, но с помощью sed ту же замену можно выполнить в одно действие:

[me@linuxbox ~]$ sed 's/([0-9]{2})/([0-9]{2})/([0-9]{4})$/3-1-2/' distros.txt

SUSE             10.2    2006-12-07

Fedora           10      2008-11-25

SUSE             11.0    2008-06-19

Ubuntu           8.04    2008-04-24

Fedora           8       2007-11-08

SUSE             10.3    2007-10-04

Ubuntu           6.10    2006-10-26

Fedora           7       2007-05-31

Ubuntu           7.10    2007-10-18

Ubuntu           7.04    2007-04-19

SUSE             10.1    2006-05-11

Fedora           6       2006-10-24

Fedora           9       2008-05-13

Ubuntu           6.06    2006-06-01

Ubuntu           8.10    2008-10-30

Fedora           5       2006-03-20

Прекрасный результат! Правда, команда выглядит устрашающе, но она работает. За один шаг мы изменили представление дат во всем файле. Этот пример также наглядно показывает, почему про регулярные выражения иногда в шутку говорят «только для записи». Мы можем писать их, но прочитать их порой никак не получается. Прежде чем сбежать от этой устрашающей команды, давайте посмотрим, как она была сконструирована. Во-первых, как мы уже знаем, эта команда имеет следующую структуру:

sed 's/регулярное_выражение/строка_замены/' distros.txt

Теперь разберем регулярное выражение, отыскивающее даты. Так как даты имеют формат ММ/ДД/ГГГГ и находятся в конце строки, найти их можно с помощью следующего выражения:

[0-9]{2}/[0-9]{2}/[0-9]{4}$

которому соответствуют две цифры, слеш, две цифры, слеш, четыре цифры и конец строки. Так, с регулярным выражением разобрались, а что со строкой замены? Чтобы описать ее, нам необходимо познакомиться с новой для нас особенностью регулярных выражений, которую можно использовать в некоторых приложениях, поддерживающих BRE. Эта особенность называется обратные ссылки, и действует она так: если в строке замены присутствует последовательность n, где n – число от одного до девяти, эта последовательность будет ссылаться на совпадение с соответствующим подвыражением в предшествующем регулярном выражении. Чтобы создать подвыражение, достаточно просто заключить часть регулярного выражения в круглые скобки, например:

([0-9]{2})/([0-9]{2})/([0-9]{4})$

Теперь у нас есть три подвыражения. Первому соответствует месяц, второму – число месяца и третьему – год. Соответственно строку замены можно выразить так:

3-1-2

что даст нам в результате такую последовательность: год, дефис, месяц, дефис, число месяца.

Теперь наша команда приобрела следующий вид:

sed 's/([0-9]{2})/([0-9]{2})/([0-9]{4})$/3-1-2/' distros.txt

Но остались две проблемы. Первая: дополнительные слеши в регулярном выражении запутают программу sed, когда она попытается интерпретировать команду s. Вторая: так как по умолчанию sed принимает только простые регулярные выражения, некоторые символы в нашем регулярном выражении будут интерпретироваться как литералы, а не как метасимволы. Мы решим обе проблемы, применив символы обратного слеша для экранирования нужных символов:

sed 's/([0-9]{2})/([0-9]{2})/([0-9]{4})$/3-1-2/' distros.txt

И дело в шляпе!

Другая особенность команды s – возможность использования дополнительных флагов вслед за строкой замены. Наиболее примечательным из них является флаг g, который требует от sed применить поиск с заменой к строке глобально (globally), а не только к первому найденному совпадению, как это делается по умолчанию.

Например:

[me@linuxbox ~]$ echo «aaabbbccc» | sed 's/b/B/'

aaaBbbccc

Как видите, замена была выполнена только для первого вхождения буквы b, а остальные остались нетронутыми. Добавив флаг g, можно изменить все вхождения:

[me@linuxbox ~]$ echo «aaabbbccc» | sed 's/b/B/g'

aaaBBBccc

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

# Сценарий для sed, создающий отчет о дистрибутивах Linux

1 i

Linux Distributions Report

s/([0-9]{2})/([0-9]{2})/([0-9]{4})$/3-1-2/

y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

Сохраните сценарий в файл с именем distros.sed и запустите его:

[me@linuxbox ~]$ sed -f distros.sed distros.txt

Linux Distributions Report

SUSE             10.2    2006-12-07

FEDORA           10      2008-11-25

SUSE             11.0    2008-06-19

UBUNTU           8.04    2008-04-24

FEDORA           8       2007-11-08

SUSE             10.3    2007-10-04

UBUNTU           6.10    2006-10-26

FEDORA           7       2007-05-31

UBUNTU           7.10    2007-10-18

UBUNTU           7.04    2007-04-19

SUSE             10.1    2006-05-11

FEDORA           6       2006-10-24

FEDORA           9       2008-05-13

UBUNTU           6.06    2006-06-01

UBUNTU           8.10    2008-10-30

FEDORA           5       2006-03-20

Как видите, сценарий выдал желаемый результат, но как он это сделал? Давайте вернемся еще раз к нашему сценарию. Выведем его с помощью программы cat так, чтобы она пронумеровала строки.

[me@linuxbox ~]$ cat -n distros.sed

    1   # Сценарий для sed, создающий отчет о дистрибутивах Linux

    2

    3   1 i

    4   

    5   Linux Distributions Report

    6

    7   s/([0-9]{2})/([0-9]{2})/([0-9]{4})$/3-1-2/

    8   y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

Строка с номером 1 – это комментарий. Так же как во многих конфигурационных файлах и языках программирования, широко используемых в Linux, комментарии начинаются с символа #, за которым следует пояснительный текст. Комментарии можно помещать в сценарии в любое место (только не в сами команды), и они, безусловно, полезны для всех, кто хочет выяснить особенности работы сценария или сопровождать его.

Строка 2 – это пустая строка. Так же как комментарии, мы можем добавлять пустые строки для удобочитаемости.

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

В строках с 3-й по 6-ю содержится текст, который должен быть вставлен по адресу 1, в первую входную строку. Команда i, сопровождаемая последовательностью из обратного слеша и перевода строки, производит экранированный символ перевода, или то, что мы называем символом продолжения строки. Эта последовательность используется во многих случаях, в том числе и в сценариях на языке командной оболочки, позволяя встраивать символ перевода строки в поток текста так, чтобы он не воспринимался интерпретатором (в данном случае программой sed) как конец строки. Команда i, а также команда a (добавления текста в конец) и команда c (замены текста), могут располагаться в нескольких строках текста, при условии, что каждая из них, кроме последней, будет завершаться символом продолжения строки. Шестая строка в нашем сценарии фактически завершает вставляемый текст и заканчивается уже не символом продолжения строки, а простым переводом строки, сообщая о завершении команды i.

ПРИМЕЧАНИЕ

Символ продолжения строки формируется из обратного слеша и следующего сразу за ним перевода строки. Никаких промежуточных пробелов между ними быть не должно.

Строка 7 – наша команда поиска с заменой. Так как ей не предшествует никакой конкретный адрес, она будет выполнена для каждой строки во входном потоке.

Строка 8 выполняет перекодировку букв нижнего регистра в буквы верхнего регистра. Обратите внимание, что, в отличие от программы tr, команда y в sed не поддерживает ни диапазоны символов (например, [a-z]), ни классы символов POSIX. И снова, так как команде y не предшествует никакой конкретный адрес, она будет выполнена для каждой строки во входном потоке.

использующие sed также часто выбирают...

Программа sed обладает очень широкими возможностями. С ее помощью можно решать весьма сложные задачи, связанные с редактированием потока текста. Но чаще она используется для выполнения простеньких операций, определение которых укладывается в одну строку. Для решения объемных задач многие предпочитают использовать другие инструменты. Наиболее популярными из них являются awk и perl. Они не относятся к разряду простых инструментов, как программы, обсуждаемые здесь, а являются полноценными языками программирования. perl, например, часто применяется взамен языка командной оболочки для решения многих задач системного администрирования, а также пользуется большой популярностью как средство разработки веб-приложений. awk имеет более узкую область применения. Основное его достоинство заключается в возможности управления табличными данными. Он напоминает sed в том смысле, что программы на awk обычно занимаются построчной обработкой текстовых файлов, используя схему, похожую на адреса в sed со следующими за ними операциями. Даже при том, что обсуждение awk и perl выходит за рамки этой книги, они являются отличными инструментами для пользователей командной строки в Linux.

aspell – интерактивная проверка орфографии

Последний инструмент, который мы рассмотрим в этой главе, – программа aspell, интерактивное средство проверки орфографии. Программа aspell является преемницей программы ispell, существовавшей прежде, и может использоваться как ее замена. Чаще всего программа aspell используется другими программами в тех случаях, когда необходима функция проверки орфографии, однако aspell может также весьма эффективно использоваться как самостоятельный инструмент командной строки. Она способна проверять текстовые файлы разных типов, включая документы HTML, программы на C/C++, электронные письма и другие специальные виды текста.

Чтобы проверить орфографию в файле с простым текстом, можно вызвать aspell, как показано ниже:

aspell check текстовый_файл

где текстовый_файл – это имя файла для проверки. В качестве практического примера создадим простой текстовый файл с именем foo.txt, содержащий несколько произвольных орфографических ошибок:

[me@linuxbox ~]$ cat > foo.txt

The quick brown fox jimped over the laxy dog.

Затем проверим файл с помощью aspell:

[me@linuxbox ~]$ aspell check foo.txt

Поскольку в режиме проверки (check) программа aspell действует интерактивно, вы увидите следующий экран:

The quick brown fox jimped over the laxy dog.

______________________________________________________________

1) jumped                               6) wimped

2) gimped                               7) camped

3) comped                               8) humped

4) limped                               9) impede

5) pimped                               0) umped

i) Ignore                               I) Ignore all

r) Replace                              R) Replace all

a) Add                                  l) Add Lower

b) Abort                                x) Exit

______________________________________________________________

?

В верхней части экрана выводится текст с выделенным подозрительным словом. В середине – 10 вариантов исправления ошибки, пронумерованных от 0 до 9, а затем следует список других возможных действий. Наконец, в самом низу выводится приглашение к вводу, готовое принять наш выбор.

Если ввести 1, aspell заменит подозрительное слово jimped словом jumped и перейдет к следующему подозрительному слову, laxy. Если выбрать вариант замены lazy, aspell выполнить подстановку и завершится (так как ошибок во введенной фразе больше нет). После того как aspell завершится, заглянем в файл и увидим, что все ошибки исправлены:

[me@linuxbox ~]$ cat foo.txt

The quick brown fox jumped over the lazy dog.

Если вызвать программу aspell без параметра –dont-backup, она создаст резервную копию файла с исходным текстом, добавив к имени файла расширение .bak.

А теперь похвастаемся умением пользоваться программой sed и вернем наши ошибки на место, чтобы продолжить эксперименты с нашим файлом:

[me@linuxbox ~]$ sed -i 's/lazy/laxy/; s/jumped/jimped/' foo.txt

Параметр -i сообщает программе sed, что требуется отредактировать файл «на месте», в том смысле, что изменения нужно произвести в самом файле, а не переслать их в стандартный вывод. Здесь также показана возможность передать более одной команды редактирования, разделив их точкой с запятой.

Далее мы посмотрим, как aspell справляется с текстовыми файлами разных видов. С помощью текстового редактора, например vim (наиболее смелые могут попробовать использовать sed), добавим в файл немного разметки HTML:

    

        Mispelled HTML file

    

    

        

The quick brown fox jimped over the laxy dog.

    

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

[me@linuxbox ~]$ aspell check foo.txt

мы получим следующее:

    

        Mispelled HTML file

    

    

        

The quick brown fox jimped over the laxy dog.

    

______________________________________________________________

1) HTML                                 4) Hamel

2) ht ml                                5) Hamil

3) ht-ml                                6) hotel

i) Ignore                               I) Ignore all

r) Replace                              R) Replace all

a) Add                                  l) Add Lower

b) Abort                                x) Exit

______________________________________________________________

?

aspell посчитала, что HTML-теги записаны с ошибками. Эту проблему можно преодолеть, передав параметр -H (HTML) режима проверки:

[me@linuxbox ~]$ aspell -H check foo.txt

Теперь результат будет выглядеть так:

    

        Mispelled HTML file

    

    

        

The quick brown fox jimped over the laxy dog.

    

______________________________________________________________

1) Mi spelled                           6) Misapplied

2) Mi-spelled                           7) Miscalled

3) Misspelled                           8) Respelled

4) Dispelled                            9) Misspell

5) Spelled                              0) Misled

i) Ignore                               I) Ignore all

r) Replace                              R) Replace all

a) Add                                  l) Add Lower

b) Abort                                x) Exit

______________________________________________________________

?

Теперь теги HTML игнорируются, и проверке подвергаются только фрагменты файла, не являющиеся частью разметки. В этом режиме содержимое HTML-тегов игнорируется и не проверяется, исключение составляет содержимое тегов ALT (точнее, атрибутов alt), которое будет проверяться в этом режиме проверки.

ПРИМЕЧАНИЕ

По умолчанию aspell игнорирует адреса URL и электронной почты в тексте. Эту ситуацию можно изменить с помощью параметров командной строки. Также можно указать, какие теги разметки должны проверяться, а какие пропускаться. За подробностями обращайтесь к странице справочного руководства (man) для aspell.

Заключительное замечание

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

Дополнительное задание

Существует несколько интересных команд обработки текста, на которые стоит обратить внимание. Среди них split (разбивает файлы на фрагменты), csplit (разбивает файлы на фрагменты, опираясь на контекст) и sdiff (выводит различия между файлами, что называется, «бок о бок»).

12 Английский аналог фразы: «Съешь же ещё этих мягких французских булок, да выпей чаю», содержащей все буквы алфавита. В этой главе, чтобы избежать полного переписывания всех авторских примеров, мы будем работать с ней. – Примеч. ред.


    Ваша оценка произведения:

Популярные книги за неделю