Подтвердить что ты не робот

Как команда "N" работает в sed?

без преамбулы,

$ cat in.txt 
 a
 b
 c
 d
$ sed '=;N' in.txt 
1
 a
 b
3
 c
 d

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

$ sed 'N;$!P;$!D;$d' thegeekstuff.txt

(Я видел это здесь) В приведенном выше примере удаляются последние две строки файла. Это работает не только файл с пронумерованной строкой, но и файл с нечетной строкой. Таким образом, в этом примере команда "N" выполняется в каждой строке.
Какая разница?

И не могли бы вы рассказать мне, почему я не вижу последнюю строку, когда я запускаю sed так?

# sed N odd-lined-file.txt
4b9b3361

Ответ 1

Выдержка из info sed:

`sed' operates by performing the following cycle on each lines of
input: first, `sed' reads one line from the input stream, removes any
trailing newline, and places it in the pattern space.  Then commands
are executed; each command can have an address associated to it:
addresses are a kind of condition code, and a command is only executed
if the condition is verified before the command is to be executed.
...
When the end of the script is reached, unless the `-n' option is in
use, the contents of pattern space are printed out to the output
stream,
...
Unless special commands (like 'D') are used, the pattern space is
deleted between two cycles

...

`N'
     Add a newline to the pattern space, then append the next line of
     input to the pattern space.  If there is no more input then `sed'
     exits without processing any more commands.

...

`D'
     Delete text in the pattern space up to the first newline.  If any
     text is left, restart cycle with the resultant pattern space
     (without reading a new line of input), otherwise start a normal
     new cycle.

Это должно в значительной степени решить ваш запрос. Но все же я попытаюсь объяснить ваши три разных случая:

CASE 1:

  • sed читает строку с ввода. [ Теперь в пространстве рисунка есть 1 строка.]
  • = Печать текущей строки.
  • N читает следующую строку в пространстве шаблонов. [ Теперь в пространстве рисунка есть 2 строки.]
    • Если нет следующей строки для чтения, то здесь выйдет sed. [ , т.е. в случае нечетных линий, sed выходит здесь - и, следовательно, последняя строка проглатывается без печати. ​​]
  • sed печатает пространство рисунка и очищает его. [ Пустое пространство шаблона.]
  • Если EOF достигло sed, выйдет здесь. Else Перезапустите полный цикл с шага 1. [, т.е. в случае четных строк sed выходит здесь.]

Сводка: В этом случае sed считывает 2 строки и печатает по 2 строки за раз. Последняя строка проглатывается, там есть нечетные строки (см. Шаг 3).

CASE 2:

  • sed читает строку с ввода. [ Теперь в пространстве рисунка есть 1 строка.]
  • N читает следующую строку в пространстве шаблонов. [ Теперь в пространстве шаблонов есть 2 строки.]
    • Если здесь не удается выйти. Это происходит, только если есть 1 строка.
  • Если его не последняя строка ($!) печатает первую строку (P) из пространства шаблонов. [ Отпечатано первая строка из пространства шаблонов. Но все еще есть 2 строки в пространстве шаблонов.]
  • Если его не последняя строка ($!) удаляет первую строку (D) из пространства шаблонов [ Теперь в пространстве шаблона имеется только одна строка (вторая).] и перезапустить командный цикл с шага 2. И его из-за команды D (см. выдержку выше).
  • Если его последняя строка ($), то удалите (D) полное пространство шаблонов. [То есть. достигнуто EOF] [ . Перед началом этого шага в пространстве шаблонов было 2 строки, которые теперь очищены D - в конце этого шага пространство шаблонов пуст.]
  • sed автоматически останавливается на EOF.

Резюме: В этом случае:

  • sed сначала считывает 2 строки.
  • если доступна следующая строка для чтения, распечатайте первую строку и прочитайте следующую строку.
  • иначе удалите обе строки из кеша. Таким образом, он всегда удаляет последние две строки.

CASE 3:
В том же случае, что и CASE: 1, просто удалите из него Шаг 2.