Оболочка: вставить пустую / новую строку двумя линиями над шаблоном - PullRequest
6 голосов
/ 16 апреля 2009

Чтобы добавить пустую строку над каждой строкой, соответствующей вашему регулярному выражению, вы можете использовать:

sed '/regexp/{x;p;x;}'

Но я хочу добавить пустую строку, не на одну строку выше, а на две строки выше строки, которая соответствует моему регулярному выражению.

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

Вот фрагмент формата текста:

случайная информация (принадлежит предыдущему бизнесу)
название компании
служебный адрес

Например:

Разговорные языки: английский
Бухта Арнольда, Нфлд (к югу от Кларенвилля)
Нил Роуд, Арнольдс Коув, Северная Дакота, A0B1N0

Я хотел бы добавить новую строку над названием компании:

Разговорные языки: английский

Бухта Арнольда, Нфлд (к югу от Кларенвилля)
Нил Роуд, Арнольдс Коув, Северная Дакота, A0B1N0

Ответы [ 6 ]

7 голосов
/ 17 апреля 2009

Более читаемый Perl, и обрабатывает несколько файлов разумно.

#!/usr/bin/env perl
use constant LINES => 2;
my @buffer = ();
while (<>) {
    /pattern/ and unshift @buffer, "\n";
    push @buffer, $_;
    print splice @buffer, 0, -LINES;
}
continue {
    if (eof(ARGV)) {
        print @buffer;
        @buffer = ();
    }
}
5 голосов
/ 17 апреля 2009

Нечто похожее на ваш оригинальный подход в sed:

sed '/regexp/i\

$H
x'

Основная идея состоит в том, чтобы напечатать все с задержкой на одну строку ( x изменить пробелы удержания и узора - печать неявна) Это необходимо сделать, потому что пока мы не проверим, соответствует ли следующая строка регулярному выражению, мы не знаем, i - вставить новую строку или нет.

($ H - это просто хитрость для печати последней строки. Она добавляет последнюю строку в буфер хранения, так что последняя неявная команда печати тоже выводит ее.)

3 голосов
/ 17 апреля 2009

Simple:

sed '1{x;d};$H;/regexp/{x;s/^/\n/;b};x'

Опишите это

#!/bin/sed

# trick is juggling previous and current line in hold and pattern space

1 {         # at firs line
  x         # place first line to hold space
  d         # skip to end and avoid printing
}
$H          # append last line to hold space to force print
/regexp/ {  # regexp found (in current line - pattern space)
  x         # swap previous and current line between hold and pattern space
  s/^/\n/   # prepend line break before previous line
  b         # jump at end of script which cause print previous line
}
x           # if regexp does not match just swap previous and current line to print previous one

Редактировать : немного более простая версия.

sed '$H;/regexp/{x;s/^/\n/;b};x;1d'
2 голосов
/ 17 апреля 2009
perl -ne 'END{print @x} push@x,$_; if(@x>2){splice @x,1,0,"\n" if /[[:alpha:]]\d[[:alpha:]]\s?\d[[:alpha:]]\d/;print splice @x,0,-2}'

Если я вложу ваш файл в это, я получу то, что вы хотите ... это уродливо, но вы хотели оболочку (то есть однострочную) :-) Если бы я делал это в полном perl, я был бы в состоянии убрать это много, чтобы сделать его читаемым. : -)

1 голос
/ 17 апреля 2009

Вот подход, который работает для Python.

import sys
def address_change( aFile ):
    address= []
    for line in aFile:
        if regex.match( line ):
            # end of the address
            print address[0]
            print 
            print address[1:]
            print line
            address= []
         else:
            address.append( line )
address_change( sys.stdin )

Это позволяет вам переформатировать полный адрес для вашего сердца. Вы можете расширить его, чтобы создать класс Address, если форматирование является сложным.

0 голосов
/ 16 апреля 2009

Я пытался

sed '/regexp/a\\n'

но он вставил две строки. Если тебя это не беспокоит, возьми.

echo -e "a \ nb \ nc" | sed '/ ^ a $ / a \ n'

B
с

Edit: Теперь, когда вы заявляете, что вам нужно вставить две строки над соответствующим регулярным выражением, предложенное регулярное выражение не будет работать.

Я даже не уверен, будет ли это вообще работать с sed, так как вам нужно помнить прошлые строки. Звучит как работа для языка более высокого уровня, такого как python или perl: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...