Почему эта линия sed делает это? - PullRequest
0 голосов
/ 14 января 2011

Почему это приводит к таким результатам?

C:\>(echo a  &&  echo b) | sed "1!G;h;$p"
a
b
a
b
a

C:\>

Added-
Теперь я вижу, что нет никаких сомнений, что это дало бы эти результаты ... но

(добавлено примечание - 2-я строка = последняя строка. Но я вижу, что вы написали последнюю строку, чтобы подчеркнуть, что это $ соответствует 2-й строке как последней строке. Я принимаю эту запись. Кроме того, 1-я строка, 2-я строка, последняя строка, см в строки ввода.)

Джонатан, ты написал
а - 1-я строка, пробел
б - 2-я строка, пробел, строка 1
а - 2-я строка, пробел, строка 2
b - последняя строка, $ p пробел, строка 1
a - последняя строка, $ p пробел, строка 2

Но не будет ли это
Примечание. Комментарий Денниса подтвердил, что «Но не будет ли» правильно

a - 1-я строка, пробел
b - последняя строка, $ p пробел, строка 1
a - последняя строка, $ p пробел, строка 2
б - 2-я строка, пробел, строка 1
а - 2-я строка, пробел, строка 2

т.е. тот же вывод
а
б
а
б

Но описания того, как это сделал b a, это наоборот

Предполагается, что $ действует в последней строке, а не после нее ..

Но то, что вы написали, выглядит так, как будто $ работает после него.

Ответы [ 2 ]

3 голосов
/ 14 января 2011
  • 1!G добавляет пространство удержания к пространству образца после первой строки.
  • h копирует пространство образца в пространство удержания (на каждой строке).
  • $p печатает последнюю строку (снова).

Первая строка ввода - 'a';команда G игнорируется;линия копируется в область удержания;строка печатается (потому что вы не сказали -n).

Вторая строка ввода - 'b';команда G добавляет пространство удержания ('a') к пространству паттерна ('b');команда 'h' копирует пространство образца в пространство удержания;Пространство шаблона печатается один раз из-за 'no -n'.

Нет больше ввода, поэтому $p действует и печатает пространство шаблона.

Итак, вы получаете:

  • a - 1-я строка, пробел
  • b - 2-я строка, пробел, строка 1
  • a - 2-я строка,пробел, строка 2
  • b - последняя строка, $ p пробел, строка 1
  • a - последняя строка, $ p пробел, строка 2

Вопрос задается: пометил ли я пары строк 'b / a' назад?

Хороший вопрос: не уверен ... как бы мы узнали?

Давайте добавим еще одну операцию к набору '$':

(echo a; echo b) | sed -e '1!G;h;$p;$s/b\na/X'

Вывод:

a
b
a
X

, который показывает, что печать $p происходит до $s///операция, которая происходит до окончательной печати пространства шаблона.

Один побочный эффект этого наблюдения, который застал меня врасплох (но имеет смысл при отражении), заключается в том, что sed знает, когда он обрабатываетЛаСтрока st, поскольку он запускает скрипт в последней строке.Это означает, что после перевода строки выполняется упреждающее чтение, чтобы узнать, есть ли еще данные для извлечения. Деннис Уильямсон показывает, что источник sed в строке 928 содержит функцию test_eof(), которая действительно выполняет один символ прогнозирования.

(Одно из преимуществ SO - это то, что вы учитесь, даже когда учите!)

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

0 голосов
/ 30 июля 2014

первая строка ввода - «а» вторая строка ввода 'b'

Sed считывает первую строку ввода (a) в пространство образца и выполняет команды. Из команд, которых три. 1! G пропускается, так как это применимо (добавление пространства образца к пространству удержания), когда это не первая строка. h копирует пространство шаблона в пространство хранения. $ p не применяется. Затем после выполнения команд печатает пространство шаблона. Он печатает «а». Обратите внимание, что пространство для удержания по-прежнему равно «a» и будет даже сразу после считывания следующей строки в пространство шаблона. Пространство шаблона в настоящее время 'a', но изменится, будучи перезаписанным, когда будет прочитана следующая строка.

Sed считывает вторую строку ввода (b) в пространство образца, обратите внимание, что пространство удержания по-прежнему равно 'a' Затем он запускает 1! G, добавляя пространство удержания (a) к пространству образца (b), давая пространство образца "b \ na" и пространство хранения "a". Следующая команда - это «h», которая копирует пространство образца (b \ na) в пространство удержания, давая пространство удержания «b \ na», хотя мы видим, что пространство удержания здесь не так уж важно. Следующая команда - это $ p, которая применяется, поскольку вторая строка ввода (то есть строка ввода, на которой мы находимся) также является последней строкой ввода, и, как уже упоминалось, $ p применяет и печатает пространство шаблона, поэтому мы получаем b \ н печатается. Затем пространство шаблона печатается снова, потому что, как и в первой строке, после выполнения всех команд пространство шаблона печатается. Таким образом, читая вторую строку ввода (которая является последней строкой ввода), мы получаем b \ na и снова b \ na. Первое вхождение b \ na от $ p, второе вхождение от печати пространства шаблона, которое происходит после выполнения всех команд.

a  <------- Reading first line of input. Printing the pattern space that happens after the end of the commands.
b\na     <---- Reading second line of input(which is the last line of input), hitting the $p command. That command didn't apply in the case of the first line of input.
b\na  <--- Still on the second line of input(which is the last line of input), printing the pattern space that happens after the end of the  commands. 

(обратите внимание, можно спросить .. должно ли это быть \ n, а b \ na \ nie не должно быть символа новой строки в конце пространства шаблона, поскольку они являются строками ... и * nix использует \ n как разделитель строк, а не разделитель строк. Может быть .. Но я думаю, что в случае пространства шаблонов sed у него, возможно, нет конца \ n. Я прочитал в руководстве по sed, что команды добавления работают так, что , если они хотят добавить 'текст' к пространству образца или удерживающему пространству, они добавляют \ n, сопровождаемый этим 'текстом'. Это означает, что пространство образца не заканчивается на \ n, но я не эксперт )

...