【问题标题】:Inserting text below and above a matched pattern在匹配模式的下方和上方插入文本
【发布时间】:2013-08-31 08:03:30
【问题描述】:

首先,感谢我们拥有如此精彩的社区!!我一直受益于在 stackoverflow 上分享的丰富知识。

解决我面临的问题:

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

例如

文件1.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    

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

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

所以输出看起来像:

#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    

我有一个这样的匹配列表。例如,我在这里搜索 PARENT1_H、PARENT2_H 等,但我更喜欢 GRANDPARENT1_H、GREATGRANDPARENT_H 等

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

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

谁能帮我编写一个使用 sed/awk/perl 执行此操作的脚本。或者任何其他语言/脚本(bash 等)也很棒!

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

非常感谢:-)

最好的问候, 马克

【问题讨论】:

    标签: regex perl unix sed awk


    【解决方案1】:

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

    #!/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"}
    }
    

    输出:

    #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
    

    【讨论】:

    • #endif 在错误的位置,se O/P 请求。 #endif below #endif 这是Parent1.h的正下方
    • 非常感谢您的解决方案!
    【解决方案2】:

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

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

    【讨论】:

    • 非常感谢!!这很有帮助。我用过这个,效果很好!
    【解决方案3】:
    $ 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
    

    【讨论】:

    • 非常感谢!!这很有帮助。我用过这个,效果很好。
    • 如果您对它感到满意,请记得点击答案旁边的复选标记,这样其他人就不会浪费时间为您想出替代方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 2012-07-26
    • 2018-11-13
    • 1970-01-01
    相关资源
    最近更新 更多