SED: работать с последними семью строками независимо от длины файла

Я хотел бы работать с последними 7 строками файла с помощью sed независимо от длины файла.

Согласно связанному с этим вопросу, этот тип диапазона не будет работать: $-6,$ {..commands..}

Какой эквивалент будет?


sed
person tjb    schedule 23.01.2011    source источник
comment
(a) Вы не можете - sed не подходит для этой работы. (б) Если вы достаточно извращенны, чтобы настаивать, вы можете исследовать пространство хранения и пространство шаблонов и попытаться оставить только семь строк в пространстве хранения (или, может быть, 6), а затем обработать пространство удержания, когда пространство шаблона будет для последняя строка. Но это чертовски сложно - я бы не стал заморачиваться (и я делал страшные вещи с sed, но наступает момент, когда вы выбираете правильный инструмент для работы).   -  person Jonathan Leffler    schedule 24.01.2011


Ответы (5)


Направьте вывод tail -7 в sed.

tail -7 test.txt | sed -e "s/e/WWW/"

Подробнее о каналах здесь.

person Bryan    schedule 23.01.2011
comment
Брайан, я не могу использовать это решение, потому что мне нужно использовать этот диапазон вместе с другими диапазонами (например, мне нужно обработать первые шесть и последние семь строк одного и того же файла и вернуть обработанный файл. - person tjb; 24.01.2011
comment
В этом случае я бы рекомендовал использовать скрипт Python или Perl для обработки файла. (Я неравнодушен к python...) Вероятно, его будет легче поддерживать. - person Bryan; 24.01.2011

Вы можете просто переключиться с sed(1) на ed(1), команды примерно такие же. В этом случае команда такая же, за исключением отсутствия ограничений на диапазон адресов.

$ cat > fl7.ed
ed - $1 << \eof
1,7s/$/ (one of the first seven lines)/
$-6,$s/$/ (one of the last seven lines)/
w
q
eof
$ sh fl7.ed yourfile
person DigitalRoss    schedule 23.01.2011
comment
+1: Единственная загвоздка здесь, когда ввод для обработки поступает из канала, но использование ed иногда правильно. В конце концов, ed — это «стандартный текстовый редактор» (согласно руководству 7-го издания). - person Jonathan Leffler; 24.01.2011
comment
Если файл короче 13 строк, некоторые из них будут помечены дважды. - person Jonathan Leffler; 24.01.2011

perl -lne 'END{print join$\,@a,"-",@b}push@a,$_ if@a<6;push@b,$_;shift@b if@b>7'

В блоке END{} вы можете делать все, что требуется; @a содержит первые 6, @b последние 7 строк по запросу.

person user562374    schedule 23.01.2011

Это должно сработать для вас:

sed '1{N;N;N;N;N};N;$s/foo/bar/g;P;D' inputfile

Объяснение:

  • 1{N;N;N;N;N} - когда первая строка будет прочитана, загрузите пространство шаблона еще пятью строками (всего: 6 на данный момент)
  • N - добавить еще одну строку
  • $s/foo/bar/g - когда будет прочитана последняя строка, выполнить некоторую операцию над всем содержимым пространства шаблонов (последние семь строк файла). Операции могут быть более сложными, чем показано здесь
  • P - печатать тест перед первой новой строкой в ​​пространстве шаблонов
  • D — удалить только что напечатанный текст и перейти к началу скрипта (этап «добавить еще одну строку» — первая инструкция пропускается, поскольку она применяется только к первой строке в файле)
person Dennis Williamson    schedule 24.01.2011

Это может сработать для вас:

sed ':a;1,6{$!N;ba};${s/foo/bar/g;q};N;D' file

Объяснение:

  • Создайте метку цикла. :a
  • Соберите строки с 1 по 6 в пространстве шаблонов (PS). 1,6{$!N;ba}
  • Если это последняя строка, обработайте PS и выйдите, поэтому распечатайте последние семь строк. ${s/foo/bar/g;q}
  • Если это не последняя строка, добавьте следующую строку к PS. N
  • Удалить до первой новой строки и начать новый цикл без чтения новой строки. D
person potong    schedule 05.06.2012