sed '$! N; $! D' объяснение - PullRequest
       6

sed '$! N; $! D' объяснение

3 голосов
/ 27 января 2011

Я знаю, что

cat foo | sed '$!N;$!D'

напечатает последние две строки файла foo , но я не понимаю, почему.

Я прочитал справочную страницу и знаю, что N присоединяет следующую строку к текущей обрабатываемой строке и т. Д., Но кто-то может объяснить на «хорошем английском», который соответствует порядку действий, что здесь происходит, шаг за шагом?

спасибо!

Ответы [ 2 ]

4 голосов
/ 27 января 2011

Вот как выглядит этот скрипт, когда он запускается через отладчик sedsed (от Aurelio Jargas):

$ echo -e 'a\nb\nc\nd' | sed '$!N;$!D'        PATT:^a$
PATT:^a$
COMM:$ !N
PATT:^a\Nb$
COMM:$ !D
PATT:^b$
COMM:$ !N
PATT:^b\Nc$
COMM:$ !D
PATT:^c$
COMM:$ !N
PATT:^c\Nd$
COMM:$ !D
PATT:^c\Nd$
c
d

Я отфильтровал строки, которые показались бы вернымипробел ("HOLD"), так как он не используется.«PATT» показывает, что находится в пространстве шаблона, а «COMM» вводит команду, которая должна быть выполнена.«\ N» указывает на встроенную новую строку.Конечно, «^» и «$» указывают начало и конец строки.

!N добавляет следующую строку, а !D удаляет предыдущую строку и переходит в начало сценария, не делаянеявная печать.Когда читается последняя строка, тесты $! не выполняются, поэтому ничего не остается сделать, и скрипт завершает работу и выполняет неявную печать того, что остается в пространстве шаблона (поскольку -n не было указано в аргументах).

Отказ от ответственности: я участвую в проекте sedsed и внес несколько незначительных улучшений, включая расширенную поддержку цвета, добавив индикатор начала строки ^ и предварительную поддержку Python 3. Версия передового края (котораяв последнее время не тронут) здесь .

1 голос
/ 27 января 2011

$!N;$!D - это программа sed, состоящая из двух операторов: $!N и $!D.

$!N соответствует всему, кроме последней строки последнего файла ввода ($отменяется !) и запускает команду N, которая, как вы сказали, добавляет следующую строку ввода к строке, которая в данный момент находится под пристальным вниманием («пространство шаблона»).Другими словами, sed теперь имеет две строки в пространстве шаблона и переместился на следующую строку.

$!D также соответствует всему, кроме последней строки, и стирает пространство шаблона до первой новой строки,D также запрещает sed стирать все пространство шаблона при чтении следующей строки.

Таким образом, выполняемый алгоритм примерно равен:

For every line up to but not including the last {
    Read the next line and append it to the pattern space
    If still not at the last line
        Delete the first line in the pattern space
}
Print the pattern space
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...