Як надрукувати всі, крім N-ої до останнього рядка в sed?


9
  • Я хотів би зробити доповнення / "протилежне"

    sed 13q;d <file.txt
    

    Більш загально, чи можна робити такий вид доповнення / зворотного / протилежного sed? Або лише для регулярних виразів?

  • Як надрукувати всі, крім третього до останнього рядка ?. Це вимагає двох tacі врахування вперед sed? Або є спосіб змусити sedсебе рахувати ззаду?

Відповіді:


12

Частина 1

Просто dоберіть 13-й рядок:

sed '13d' <file.txt

І загальний спосіб зробити доповнення до вищезазначеного:

sed '13!d' <file.txt

Частина 2

Тому що це можна зробити:

sed -n ':a;${P;q};N;4,$D;ba' <file.txt

Зверніть увагу, що 4це на один більше, ніж вам потрібно. Тож якби ви хотіли останнього 10-го рядка, це було б 11.

Тестування за допомогою seq:

$ seq 100 | sed -n ':a;${P;q};N;4,$D;ba'
98
$ 

Спроба пояснення

:a        # define label a
${        # match the last line
    P     # print the first line of the pattern space
    q     # quit
}
N         # match all lines: append the next line to the pattern
4,${      # match the range of lines 4 to the end of the file
    D     # delete the first line of the pattern space
}
ba        # match all lines: jump back to label a 

Цінне доповнення Глена Джекмена:

Це був "лише N-й рядок". Ось "АЛЕ НЕ N-й рядок":

sed -n ':a;${s/^[^\n]*\n//;p;q};N;4,${P;D};ba'

працює з GNU sed, \nпослідовність може не працювати з іншими седами.


Я спробував це з BSD sed (OSX) і виявив, що він не дуже працює у формі вище. Виглядають проблеми:

  1. ; Використовується для розділення рядків, як правило, працює, але не працює після мітки
  2. Здається, BSD sed вимагає ;після останньої команди в однорядковій {}командній групі, тоді як GNU sed - ні
  3. \nяк правило, може бути використаний у звичайному виразі, але, мабуть, не в []дужковому виразі. Отже, щоб виключити нові рядки, ми можемо використовувати щось на зразок [[:alnum:][:punct:][:graph:][:blank:]]цього, хоча це може виключати й інші символи (зокрема інші контрольні символи).

Отже, це спроба створення більш незалежної від платформи версії:

sed -n ':a
${s/^[[:alnum:][:punct:][:graph:][:blank:]]*\n//p;q;};N;4,${P;D;};ba'

Схоже, це працює під OSX та Ubuntu.


@jimmij Інші відповіді на відповідні запитання в мережі SE припускають, що head/ tailрішення набагато повільніше, ніж sedрішення. Спасибі, хоча.
ізоморфізми

3
@isomorphismes жодна програма не може знати кількість рядків у файлі, якщо вона не пройде через весь файл. Навколо цього немає способу. Єдиний спосіб підрахунку знизу - це перевернути файл і підрахувати зверху або проаналізувати його двічі. Тож голова / хвіст збираються майже так само швидко, як це потрапляє.
тердон

@isomorphismes ... тому що вони ( head/ tail) оптимізовані для того, щоб робити те, що роблять.
петерф

@isomorphismes - відредаговано усіма потрібними вам частинами
Digital Trauma

Приємно! Мені довелося змінити свою відповідь, оскільки я якось очікував, що це буде складніше. :)
петерф
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.