Редактор потоков - циклы
Как и другие языки программирования, SED также предоставляет возможность создания циклов и ветвлений для управления потоком выполнения. В этой главе мы собираемся узнать больше о том, как использовать циклы и ответвления в SED.
Цикл в SED работает аналогично gotoзаявление. SED может перейти к строке, отмеченной меткой, и продолжить выполнение оставшихся команд. В SED мы можем определитьlabel следующим образом:
:label
:start
:end
:up
В приведенном выше примере имя после двоеточия (:) подразумевает имя метки.
Чтобы перейти к определенной метке, мы можем использовать bкоманда, за которой следует имя метки. Если имя метки опущено, SED переходит в конец файла SED.
Давайте напишем простой сценарий SED, чтобы понять циклы и ответвления. В нашем файле books.txt есть несколько записей с названиями книг и их авторами. В следующем примере название книги и имя автора объединены в одну строку, разделенную запятой. Затем ищет узор «Пауло». Если шаблон совпадает, он печатает дефис (-) перед строкой, в противном случае он переходит кPrint этикетка, на которой печатается линия.
[jerry]$ sed -n '
h;n;H;x
s/\n/, /
/Paulo/!b Print
s/^/- /
:Print
p' 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
На первый взгляд приведенный выше сценарий может показаться загадочным. Давайте демистифицируем это.
Первые две команды говорят сами за себя h;n;H;x и s/\n/, / объедините название книги и ее автора через запятую (,).
Третья команда переходит к метке Print только когда шаблон не совпадает, иначе подстановка выполняется четвертой командой.
:Print это просто название лейбла и, как вы уже знаете, p это команда печати.
Для удобства чтения каждая команда SED помещается в отдельную строку. Однако можно разместить все команды в одной строке следующим образом:
[jerry]$ sed -n 'h;n;H;x;s/\n/, /;/Paulo/!b Print; s/^/- /; :Print;p' 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