Shell: вставьте пробел/новую строку две строки выше шаблона

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

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

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

Шаблон, которому я буду соответствовать, является индексом в строке адреса.

Вот отрывок форматирования текста:

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

Например:

На языках говорят: английский язык
Бухта Arnold, Nfld (sub в Клэренвилл)
Нил Road, Arnolds-Cove, NL, A0B1N0

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

На языках говорят: английский язык

Бухта Arnold, Nfld (sub в Клэренвилл)
Нил Road, Arnolds-Cove, NL, A0B1N0

6
задан Dennis 4 January 2014 в 21:27
поделиться

6 ответов

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

sed '/regexp/i\

$H
x'

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

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

5
ответ дан 8 December 2019 в 13:02
поделиться

Более читабельный 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 = ();
    }
}
7
ответ дан 8 December 2019 в 13:02
поделиться

Простой:

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'
3
ответ дан 8 December 2019 в 13:02
поделиться
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, я мог бы многое почистить, чтобы сделать его читабельным. : -)

2
ответ дан 8 December 2019 в 13:02
поделиться

Вот подход, который работает для 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 , если ваше форматирование сложное.

1
ответ дан 8 December 2019 в 13:02
поделиться

Я попытался

sed '/regexp/a\\n'

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

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

b
c

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

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

0
ответ дан 8 December 2019 в 13:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: