Понятие 'занимать пространство' и 'шаблонов' в СЭД
меня смущают две концепции в 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.
эти шесть команд действительно сбивают меня с толку.
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С другой стороны будет выполняться только на последней строке. Так вот что происходит:
- первая строка считывается и автоматически вставляется в шаблон пространство
- в первой строке первая команда не выполняется;
hкопирует первую строку в провести пространство.- теперь вторая строка заменяет что бы ни было в пространстве шаблонов
- на второй строке, сначала мы выполняем
G, добавляя содержимое буфера удержания к буферу шаблона, разделяя его новой строкой. Пространство шаблона теперь содержит вторую строку, новую строку и первую строку.- затем,
hкоманда вставляет связанное содержимое буфера шаблонов в пространство хранения, которое теперь содержит обратные строки два и один.- мы переходим к строке Номер Три -- перейти к пункт (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появляется дважды в выходных данных.)выше объяснил:
- - n отключает вывод, если явно не печатается
- первый матч, находит и помещает Host: line в буфер удержания (h)
- второе совпадение, находит следующую информацию: строка, но сначала обменивает (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