在匹配的图案下方和上方插入文字

时间:2022-06-01 21:15:38

First of all, thanks for such a wonderful community we have!! I have always been benefited by the great knowledge shared here on *.

首先,感谢我们拥有的这样一个美好的社区!我一直受益于*上分享的丰富知识。

Coming to the problem I was facing:

来到我面临的问题:

I have a bunch of files(about 200) In those files I wanted to search for a pattern(multi-line) and if the pattern matches, I want to add some text above and below the pattern.

我有一堆文件(大约200个)在这些文件中我想搜索一个模式(多行),如果模式匹配,我想在模式的上方和下方添加一些文本。

E.g

File1.cpp

#ifndef FILE1_H
#define FILE1_H

#ifndef PARENT1_H
#include "Parent1.h"
#endif

#ifndef SIBLING_H
#include "Sibling.h"
#endif

#ifndef PARENT2_H
#include "Parent2.h"
#endif

class File1
{
};

#endif    

In this file I wanted to add #ifndef NOPARENT above #ifndef PARENT1_H and #endif below #endif which is right below Parent1.h.

在这个文件中,我想在#ifndef PARENT1_H上方添加#ifndef NOPARENT,在Parent1.h正下方的#endif下面添加#endif。

I want to do the same thing for #ifndef PARENT2_H

我想为#ifndef PARENT2_H做同样的事情

So the output will look like:

所以输出看起来像:

#ifndef FILE1_H
#define FILE1_H

#ifndef NOPARENT
#ifndef PARENT1_H
#include "Parent1.h"
#endif
#endif


#ifndef SIBLING_H
#include "Sibling.h"
#endif

#ifndef NOPARENT
#ifndef PARENT2_H
#include "Parent2.h"
#endif
#endif

class File1
{
};

#endif    

I have a list of such matches. For e.g here I was searching for PARENT1_H, PARENT2_H etc but I have more like GRANDPARENT1_H, GREATGRANDPARENT_H etc

我有这样的比赛清单。例如,我在这里搜索PARENT1_H,PARENT2_H等,但我更喜欢GRANDPARENT1_H,GREATGRANDPARENT_H等

So essentially, the approach I was thinking is, search for the input symbols(PARENT1_H etc) in those files and if a match is found, add the text(#ifndef NOPARENT) above and #endif below.

基本上,我想的方法是,在这些文件中搜索输入符号(PARENT1_H等),如果找到匹配项,则在上面添加文本(#ifndef NOPARENT),在下面添加#endif。

Input symbols are many and so are the files in which to replace.

输入符号很多,要替换的文件也是如此。

Can anyone please help me with a script which does this using sed/awk/perl. Or any other language/script(bash etc) would also be great!

任何人都可以帮助我使用sed / awk / perl执行此操作的脚本。或者任何其他语言/脚本(bash等)也会很棒!

I am novice user of sed/awk/perl so could use the help

我是sed / awk / perl的新手用户,所以可以使用帮助

Thanks a lot :-)

非常感谢 :-)

Best Regards, Marc

最诚挚的问候,马克

3 个解决方案

#1


0  

EDIT: Did not read correctly request. This seems to give correct O/P

编辑:未正确阅读请求。这似乎给出了正确的O / P.

awk '/PARENT1_H/ {print "#ifndef NOPARENT" RS $0;f=1} /#endif/ && f {print $0;f=0} !/PARENT1_H/' file

#2


1  

$ awk '/#ifndef (PARENT1_H|PARENT2_H)$/{print "#ifndef NOPARENT"; f=1} {print} f&&/#endif/{print; f=0}' file
#ifndef FILE1_H
#define FILE1_H

#ifndef NOPARENT
#ifndef PARENT1_H
#include "Parent1.h"
#endif
#endif

#ifndef SIBLING_H
#include "Sibling.h"
#endif

#ifndef NOPARENT
#ifndef PARENT2_H
#include "Parent2.h"
#endif
#endif

class File1
{
};

#endif

#3


0  

How about using a regex? Let me know if this is not what you want and I'll modify!

使用正则表达式怎么样?如果这不是您想要的,请告诉我,我会修改!

#!/usr/bin/perl -w
use strict;

my $file = 'file1.txt';
open my $input, '<', $file or die "Can't read $file: $!";

my $outfile = 'output.txt';
open my $output, '>', $outfile or die "Can't write to $outfile: $!";

while(<$input>){
    chomp;
my (@match) = ($_ =~ /\.*?(\s+PARENT\d+_H)/); # edit - only matches 'PARENT' not 'GRANDPARENT'
    if (@match){
        print $output "#ifndef NOPARENT\n";
        print $output "$_\n";
        print $output "#endif\n";
    }
    else {print $output "$_\n"}
}

Output:

#ifndef FILE1_H
#define FILE1_H

#ifndef NOPARENT
#ifndef PARENT1_H
#endif
#include "Parent1.h"
#endif

#ifndef SIBLING_H
#include "Sibling.h"
#endif

#ifndef NOPARENT
#ifndef PARENT2_H
#endif
#include "Parent2.h"
#endif

#1


0  

EDIT: Did not read correctly request. This seems to give correct O/P

编辑:未正确阅读请求。这似乎给出了正确的O / P.

awk '/PARENT1_H/ {print "#ifndef NOPARENT" RS $0;f=1} /#endif/ && f {print $0;f=0} !/PARENT1_H/' file

#2


1  

$ awk '/#ifndef (PARENT1_H|PARENT2_H)$/{print "#ifndef NOPARENT"; f=1} {print} f&&/#endif/{print; f=0}' file
#ifndef FILE1_H
#define FILE1_H

#ifndef NOPARENT
#ifndef PARENT1_H
#include "Parent1.h"
#endif
#endif

#ifndef SIBLING_H
#include "Sibling.h"
#endif

#ifndef NOPARENT
#ifndef PARENT2_H
#include "Parent2.h"
#endif
#endif

class File1
{
};

#endif

#3


0  

How about using a regex? Let me know if this is not what you want and I'll modify!

使用正则表达式怎么样?如果这不是您想要的,请告诉我,我会修改!

#!/usr/bin/perl -w
use strict;

my $file = 'file1.txt';
open my $input, '<', $file or die "Can't read $file: $!";

my $outfile = 'output.txt';
open my $output, '>', $outfile or die "Can't write to $outfile: $!";

while(<$input>){
    chomp;
my (@match) = ($_ =~ /\.*?(\s+PARENT\d+_H)/); # edit - only matches 'PARENT' not 'GRANDPARENT'
    if (@match){
        print $output "#ifndef NOPARENT\n";
        print $output "$_\n";
        print $output "#endif\n";
    }
    else {print $output "$_\n"}
}

Output:

#ifndef FILE1_H
#define FILE1_H

#ifndef NOPARENT
#ifndef PARENT1_H
#endif
#include "Parent1.h"
#endif

#ifndef SIBLING_H
#include "Sibling.h"
#endif

#ifndef NOPARENT
#ifndef PARENT2_H
#endif
#include "Parent2.h"
#endif