Редактор потока - управление шаблонами

Мы уже обсуждали использование шаблона и буфера хранения. В этой главе мы собираемся подробнее изучить их использование. Давайте обсудимnкоманда, которая печатает пространство шаблонов. Он будет использоваться вместе с другими командами. Ниже приведен синтаксис команды then.

[address1[,address2]]n

Возьмем пример.

[jerry]$ sed 'n' books.txt

Когда приведенный выше код будет выполнен, он даст следующий результат:

1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864

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

Давайте рассмотрим три команды SED перед n и две команды SED после n следующим образом:

Sed command #1 
Sed command #2 
Sed command #3 
n command 
Sed command #4 
Sed command #5

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

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

Немного доработаем файл books.txt. Скажем, файл содержит названия книг, за которыми следуют имена их авторов. После модификации файл должен выглядеть так:

[jerry]$ cat books.txt

Выполнив приведенный выше код, вы получите следующий результат:

A Storm of Swords 
George R. R. Martin 
The Two Towers 
J. R. R. Tolkien 
The Alchemist 
Paulo Coelho 
The Fellowship of the Ring 
J. R. R. Tolkien 
The Pilgrimage 
Paulo Coelho 
A Game of Thrones 
George R. R. Martin

Поменяем местами содержимое двух буферов. Например, в следующем примере печатаются только имена авторов.

[jerry]$ sed -n 'x;n;p' books.txt

Выполнив приведенный выше код, вы получите следующий результат:

George R. R. Martin 
J. R. R. Tolkien 
Paulo Coelho 
J. R. R. Tolkien 
Paulo Coelho 
George R. R. Martin

Давайте разберемся, как работает эта команда.

  • Первоначально SED считывает первую строку, т. Е. «Бурю мечей», в буфер шаблонов.

  • x команда перемещает эту строку в буфер хранения.

  • n выбирает следующую строку, то есть Джорджа Мартина, в буфер шаблона.

  • Управление переходит к команде, за которой следует n, которая печатает содержимое буфера шаблонов.

  • Процесс повторяется до тех пор, пока файл не будет исчерпан.

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

[jerry]$ sed -n 'x;n;x;p' books.txt

Выполнив приведенный выше код, вы получите следующий результат:

A Storm of Swords 
The Two Towers 
The Alchemist 
The Fellowship of the Ring 
The Pilgrimage 
A Game of Thrones

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

[address1[,address2]]h

Следующая команда печатает только названия автора Пауло Коэльо.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;p}' books.txt

Выполнив приведенный выше код, вы получите следующий результат:

The Alchemist 
The Pilgrimage

Давайте разберемся, как работает вышеуказанная команда. Содержимое books.txt имеет определенный формат. В первой строке указывается название книги, за которой следует автор книги. В приведенной выше команде "!" используется для отмены условия, т. е. строка копируется в буфер хранения только в том случае, если сопоставление с шаблоном не удается. Фигурные скобки {} используются для группировки нескольких команд SED.

В первом проходе команды SED считывает первую строку, то есть «Бурю мечей», в буфер шаблонов и проверяет, содержит ли она шаблон Пауло или нет. Поскольку сопоставление с образцом не удается, он копирует эту строку в буфер хранения. Теперь и шаблонный буфер, и буфер удержания содержат одну и ту же строку, то есть A Storm of Swords. На втором этапе проверяется, содержит ли строка узор Пауло или нет. Поскольку шаблон не совпадает, он ничего не делает.

Во втором проходе он считывает следующую строку Джорджа Мартина в буфер шаблона и выполняет те же шаги. Для следующих трех строк он делает то же самое. В конце пятого прохода оба буфера содержат The Alchemist. В начале шестого прохода он считывает строку Paulo Coelho и, поскольку шаблон совпадает, он не копирует эту строку в буфер хранения. Следовательно, буфер шаблонов содержит Пауло Коэльо, а буфер хранения содержит Алхимика.

После этого он проверяет, содержит ли буфер шаблона шаблон Пауло. При успешном совпадении с шаблоном он обменивается содержимым буфера шаблонов с буфером хранения. Теперь буфер шаблонов содержит Алхимика, а буфер удержания содержит Пауло Коэльо. Наконец, он печатает содержимое буфера шаблонов. Те же шаги применяются к выкройке «Паломничество».

В hкоманда уничтожает предыдущее содержимое буфера удержания. Это не всегда приемлемо, так как иногда нам нужно сохранить содержимое. Для этого SED предоставляетHкоманда, которая добавляет содержимое в буфер удержания, добавляя новую строку в конце. Единственная разница междуh и Hкоманда, первая перезаписывает данные из буфера удержания, а вторая добавляет данные в буфер удержания. Его синтаксис похож наh команда.

[address1[,address2]]H

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

[jerry]$ sed -n '/Paulo/!h; /Paulo/{H;x;p}' books.txt

Выполнив приведенный выше код, вы получите следующий результат:

The Alchemist 
Paulo Coelho 
The Pilgrimage
Paulo Coelho

Мы узнали, как копировать / добавлять содержимое буфера шаблонов для хранения буфера. Можем ли мы выполнить и обратную функцию? Да, конечно! Для этого SED предоставляетgкоманда, которая копирует данные из буфера хранения в буфер шаблона. При копировании существующие данные из пространства шаблонов перезаписываются. Ниже приведен синтаксисg команда.

[address1[,address2]]g

Рассмотрим тот же пример - печатные названия книг и их авторов. На этот раз мы сначала выведем имя автора, а в следующей строке - название соответствующей книги. Следующая команда печатает имя автора Пауло Коэльо, за которым следует название книги.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{p;g;p}' books.txt

Выполнив приведенный выше код, вы получите следующий результат:

Paulo Coelho 
The Alchemist 
Paulo Coelho 
The Pilgrimage

Первая команда остается как есть. В конце пятого прохода оба буфера содержат The Alchemist. В начале шестого прохода он считывает строку Paulo Coelho и, поскольку шаблон совпадает, он не копирует эту строку в буфер хранения. Следовательно, пространство шаблонов содержит Пауло Коэльо, а пространство удержания содержит Алхимика.

После этого он проверяет, содержит ли пространство шаблонов шаблон Пауло. При успешном сопоставлении с шаблоном сначала печатается содержимое пространства шаблонов, т. Е. Пауло Коэльо, а затем он копирует буфер хранения в буфер шаблона. Следовательно, и шаблон, и буферы удержания содержат The Alchemist. Наконец, он печатает содержимое буфера шаблонов. Те же шаги применяются к выкройке «Паломничество».

Точно так же мы можем добавить содержимое буфера удержания в буфер шаблона. SED предоставляетG команда, которая добавляет содержимое в буфер шаблона, добавляя новую строку в конце.

[address1[,address2]]G

Теперь давайте возьмем предыдущий пример, в котором напечатано имя автора Пауло Коэльхоф, за которым следует название книги. Чтобы добиться того же результата, выполните следующую команду SED.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{G;p}' books.txt

Выполнив приведенный выше код, вы получите следующий результат:

Paulo Coelho 
The Alchemist 
Paulo Coelho 
The Pilgrimage

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

[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;G;p}' books.txt

Выполнив приведенный выше код, вы получите следующий результат:

The Alchemist 
Paulo Coelho 
The Pilgrimage 
Paulo Coelho