Понятие 'занимать пространство' и 'шаблонов' в СЭД



меня смущают две концепции в sed: пространство удержания и пространство шаблонов. Может кто-нибудь помочь объяснить их?



вот фрагмент руководства:




h H    Copy/append pattern space to hold space.
g G Copy/append hold space to pattern space.

n N Read/append the next line of input into the pattern space.



эти шесть команд действительно сбивают меня с толку.

692   3  

3 ответов:

когда sed читает файл строка за строкой, строка, которая была прочитана в данный момент вставляется в pattern буфера (модели пространства). Буфер шаблонов похож на временный буфер, блокнот, в котором хранится текущая информация. Когда вы говорите sed печатать, он печатает буфер шаблонов.

Hold buffer / hold space - это как долгосрочное хранилище, так что вы можете поймать что-то, сохранить его и повторно использовать позже, когда sed обрабатывает другую строку. Вы не непосредственно обработайте пространство удержания, вместо этого вам нужно скопировать его или добавить в пространство шаблона, если вы хотите что-то с ним сделать. Например, команда print p выводит только пространство шаблона. Аналогично,s работает на пространстве шаблона.

вот пример:

sed -n '1!G;h;$p'

(опция-n подавляет автоматическую печать строк)

здесь есть три команды:1!G,h и $p. 1!G присвоен адрес, 1 (первый линия), но ! означает, что команда будет выполняться везде но на первой линии. $p С другой стороны будет выполняться только на последней строке. Так вот что происходит:

  1. первая строка считывается и автоматически вставляется в шаблон пространство
  2. в первой строке первая команда не выполняется;h копирует первую строку в провести пространство.
  3. теперь вторая строка заменяет что бы ни было в пространстве шаблонов
  4. на второй строке, сначала мы выполняем G, добавляя содержимое буфера удержания к буферу шаблона, разделяя его новой строкой. Пространство шаблона теперь содержит вторую строку, новую строку и первую строку.
  5. затем, h команда вставляет связанное содержимое буфера шаблонов в пространство хранения, которое теперь содержит обратные строки два и один.
  6. мы переходим к строке Номер Три -- перейти к пункт (3) выше.

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

@Ed Morton: не согласен с вами здесь. Я нашел sed очень полезным и простым (как только вы Грок концепцию шаблона и удерживайте буферы), чтобы придумать элегантный способ сделать многострочный грэппинг.

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

Host: foo1
some junk, doesnt matter
some junk, doesnt matter
Info: about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Info: a second line about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Host: foo2
some junk, doesnt matter
Info: about foo2 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter

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

sed -n '/Host:/{h}; /Info/{x;p;x;p;}' myfile.txt

выход выглядит так:

Host: foo1
Info: about foo1 that I really care about!!
Host: foo1
Info: a second line about foo1 that I really care about!!
Host: foo2
Info: about foo2 that I really care about!!

(обратите внимание, что Host: foo1 появляется дважды в выходных данных.)

выше объяснил:

  1. - n отключает вывод, если явно не печатается
  2. первый матч, находит и помещает Host: line в буфер удержания (h)
  3. второе совпадение, находит следующую информацию: строка, но сначала обменивает (x) текущую строку в буфере шаблонов с буфером удержания и печатает (p) хост: линия, затем повторно обменивается (x) и печатает (p) информацию: линия.

Да, это упрощенный пример, но я подозреваю, что это общая проблема, которая была быстро решена с помощью простого sed one-liner. Для гораздо более сложных задач, таких как те, в которых вы не можете полагаться на заданную предсказуемую последовательность, awk может быть лучше подходит.

хотя ответ @January и пример хороши, объяснения было недостаточно для меня. Мне пришлось много искать и учиться, пока я не понял, как именно sed -n '1!G;h;$p' строительство. Поэтому я хотел бы подробно рассказать о команде для кого-то вроде меня.

прежде всего, давайте посмотрим, что команда делает.

$ echo {a..d} | tr ' ' '\n' # Prints from 'a' to 'd' in each line
a
b
c
d
$ echo {a..d} | tr ' ' '\n' | sed -n '1!G;h;$p'
d
c
b
a

он меняет вход, как .

$ echo {a..d} | tr ' ' '\n' | sed -n '1!G;h;l;$p'
a$
b\na$
c\nb\na$
d\nc\nb\na$
d
c
b
a

я нашел это очень полезным, чтобы посмотреть это видео-учебник понимание того, как СЭД работает, как парня показывает, как каждое пространство будет использоваться шаг за шагом. Удержание разнесено упоминается в 4-м учебнике, но я рекомендую смотреть все видео, Если вы не знакомы с sed.

и GNU sed document и учебник Брюса Барнетта очень хорошие ссылки.

Comments

    Ничего не найдено.