Regex 排除正则表达式匹配中的字符串,用于sed处理

Regex 排除正则表达式匹配中的字符串,用于sed处理,regex,sed,Regex,Sed,我需要将此匹配为替换命令: whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever 我正在尝试: sed -e 's/__\(.*\)__/\{{\1}}/g' myfile 但这是急切地匹配\u匹配\u这个\u什么东西\u和\u这个\u,产生: whatever{{MATCH_THIS__whateverwhatever__AND_THIS}}whateverwhatever 但我想: whatever{{MA

我需要将此匹配为替换命令:

whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever
我正在尝试:

sed -e 's/__\(.*\)__/\{{\1}}/g' myfile
但这是急切地匹配
\u匹配\u这个\u什么东西\u和\u这个\u
,产生:

whatever{{MATCH_THIS__whateverwhatever__AND_THIS}}whateverwhatever
但我想:

whatever{{MATCH_THIS}}whateverwhatever{{AND_THIS}}whateverwhatever

如何在匹配部分中指定要排除的字符串?我知道如何排除一个字符(例如
[^a]
),但不知道如何排除字符串。

sed
不支持PCRE操作,例如非贪婪运算符

我可以通过以下变化绕过您的情况:

echo 'whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever' |
sed -e 's/__\([^_]\+_[^_]\+\)__/\{{\1}}/g'
whatever{{MATCH_THIS}}whateverwhatever{{AND_THIS}}whateverwhatever

您需要的是一个非贪婪的正则表达式,但不幸的是sed不允许这样做。但是,它可以在perl中完成

perl -pe 's|__(.*?)__|{{$1}}|g' <myfile

这是Perl,有无数种方法可以实现

使用
sed的一种方法
,尽管很明显,这不是完成这项工作的最佳工具。我对代码进行了注释,以查看发生了什么,因为它似乎有点混乱:

sed -n '
    ## Insert a newline just before each "__". This is the most
    ## important instruction of all the script. The game is that
    ## newline character is the only want that sed cannot find in
    ## a line of data, so use it to know where there will be "__"
    ## to change. For each part changed the script will save it
    ## in hold space, but due to constraints of those (only two
    ## spaces) I will have to play deleting and recovering data
    ## several times between both.
    s/__/\n&/g

    ## Save in hold space all data until first newline.
    ## So it means, just before the first "__" of the line.
    h ; s/\n.*$// ; x

    ## Remove that part just saved in hold space.
    s/^[^\n]*\n//

    ## Set a label to jump it later.
    :a

    ## This is end condition. When not found any newline
    ## in the pattern space means that there are no more "__" to 
    ## process, so get all data saved in hold space, print
    ## it and leave hold space empty ready for next line of 
    ## the input file.
    /^[^\n]\+$/ {
        g
        p
        x
        s/^.*$//
        x
        b
    }

    ## This part of code will process next two input lines.
    ## First one has the first pair of "__" and second one has
    ## the end pair, so substitute to each respective curly
    ## braces.
    s/__/{{/

    ## Once the substitution has been done, save it adding to
    ## hold space.
    ## I add all the line but only want to keep until first newline.
    ## I delete two of them because "H" command adds it one by itself.
    H ; x ; s/\n// ; s/\n.*$// ; x

    ## Delete part just processed and saved in hold space.
    s/^[^\n]*\n//

    ## Repeat same process for end pair of "__"
    s/__/}}/
    H ; x ; s/\n// ; s/\n.*$// ; x
    s/^[^\n]*\n//

    ## Goto label "a"
    ba 
' infile
从命令行粘贴并运行它,如果它产生以下结果,请使用两行代码:

whatever{{MATCH_THIS}}whateverwhatever{{AND_THIS}}whateverwhatever
exten => s,n,ExecIf($[${amacode} == 1]?Set(rateparams_view={{INCOMING_RATEPARAMS_VIEW}}):Set(rateparams_view={{OUTGOING_RATEPARAMS_VIEW}}))

这适用于我的windows XP笔记本电脑

input command
echo whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever|sed -f a.sed
output
whatever{{__MATCH_THIS__}}whateverwhatever{{__AND_THIS__}}whateverwhatever
where a.sed is this

    /__MATCH_THIS__/{
    /__AND_THIS__/{
    s/__MATCH_THIS__/\{\{__MATCH_THIS__\}\}/
    s/__AND_THIS__/\{\{__AND_THIS__\}\}/
    }
    }
逗号分隔符 输入:

whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever
blah__XXX_XX__blah_blah_blah__XX_XXX__whateverwhatever
输出:

whatever{{MATCH_THIS}}whateverwhatever{{AND_THIS}}whateverwhatever
blah{{XXX_XX}}blah_blah_blah{{XX_XXX}}whateverwhatever
这可能适用于您(GNU-sed):

或者,也许更容易理解:

sed -r 's/__/\n/g;s/\n([^\n]*)\n/{{\1}}/g;s/\n/__/g' file

它看起来很有希望,但看看这个输入数据:
extn=>s,n,ExecIf($[${amacode}==1]?Set(rateparams\u view=\uuuuuu INCOMING\urateparams\u view):Set(rateparams\u view=\uu outing\urateparams\u view))
@gonvaled,啊,你刚刚把我的门柱移到那里:-)。我不确定它是否在
sed
处理您的问题的能力范围内。是否所有sed脚本都与perl兼容?也就是说,如果我有一个正在工作的sed脚本,我可以将它提供给
perl-pe
,并希望它能正常工作吗?我问这个问题的原因是,我通常使用sed进行重构,知道sed的局限性后,我会转向perl,但我不想在将来有什么惊喜。可能不会直接问。有一个名为s2p的脚本,据说它可以在两者之间转换,但我从来没有让它做过任何事情,只是产生错误!奇怪的是,我使用sed进行了很多perl重构!谢谢顺便问一下,如何使用perl将脚本保存在文件中?告诉perl的标志是什么:正则表达式在文件
my.regex
中?
whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever
blah__XXX_XX__blah_blah_blah__XX_XXX__whateverwhatever
whatever{{MATCH_THIS}}whateverwhatever{{AND_THIS}}whateverwhatever
blah{{XXX_XX}}blah_blah_blah{{XX_XXX}}whateverwhatever
sed -r 's/__([^_]+(_[^_]+)*)__/{{\1}}/g' file
sed -r 's/__/\n/g;s/\n([^\n]*)\n/{{\1}}/g;s/\n/__/g' file