сопоставлять и заменять несколько новых строк однострочным SED или PERL - PullRequest
3 голосов
/ 29 июля 2010

У меня есть входной файл C (myfile.c), который выглядит следующим образом:

void func_foo();
void func_bar();

//supercrazytag

Я хочу использовать команду оболочки для вставки новых прототипов функций, так что вывод будет:

void func_foo();
void func_bar();
void func_new();

//supercrazytag

До сих пор мне не удавалось использовать SED или PERL.Что не сработало:

sed 's|\n\n//supercrazytag|void func_new();\n\n//supercrazytag|g' < myfile.c
sed 's|(\n\n//supercrazytag)|void func_new();\1|g' < myfile.c

Использование тех же шаблонов с perl -pe "....." также не сработало.

Чего мне не хватает?Я пробовал много разных подходов, включая , и , и , .

Ответы [ 4 ]

11 голосов
/ 29 июля 2010

Для "perl -pe" ваша проблема в том, что он обрабатывает построчно, поэтому нет способа найти "\ n \ n".Если вы добавите флаг -0777 в Perl (чтобы он обрабатывал весь файл сразу), он будет работать:

perl -0777 -pe "s|(\n\n//supercrazytag)|\nvoid func_new();$1|g" myfile.c

Я также изменил (не рекомендуется для этого использования) \ 1 на $ 1 и добавилдополнительные \ n к началу замены для удобства чтения.

См. perlrun (Командные переключатели) для объяснения странного вида "-0777"

2 голосов
/ 29 июля 2010

Это будет работать:

sed '/^$/N;s|\n//supercrazytag|void func_new();\n\n//supercrazytag|' myfile.c

EDIT
Или более кратко:

sed '/^$/N;s|\(\n//supercrazytag\)|void func_new();\n\1|' myfile.c
0 голосов
/ 30 июля 2010
awk  '/supercrazy/{$0="void func_new()\n\n"$0}1'  file
0 голосов
/ 29 июля 2010

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

В псевдокоде:
1. начать чтение и запись строкиз файла
2. когда мы найдем конец раздела прототипа, вставьте новый текст

use strict;
use warnings;

my $new_prototype = 'void func_new();';
my $seen_proto;

while (<>)
{
    if (/^void \w+\(\);$/ .. /^$/)
    {
        # in the middle of the prototype section
        $seen_proto = 1;
    }
    else
    {
        # this code is run when either before or after the prototype section

        # if we have seen prototypes, we're just after that section - print
        # out the new prototype and then reset our flag so we don't do it twice
        print "$new_prototype\n" and $seen_proto-- if $seen_proto;
    }

    # print out the original line
    print;
}

Поместите этот код в process.pl и запустите через: perl process.pl < mycode.cpp > mycode_new.cpp

...