За выключэннем радкі ў рэгулярных выразаў адпаведнасці, для апрацоўкі SED

Мне трэба, каб адпавядаць гэтаму для замяняе каманды:

whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever

Я спрабую з:

sed -e 's/__\(.*\)__/\{{\1}}/g' myfile

Але гэта ахвотна адпаведнасць __ MATCH_THIS__whateverwhatever__AND_THIS __ , вытворчасць:

whatever{{MATCH_THIS__whateverwhatever__AND_THIS}}whateverwhatever

Але я хацеў:

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

Як я магу пазначыць радок, каб выключыць, у якая ўзгадняе часткі? Я ведаю, як выключыць адзін сімвал (напрыклад, [^ а] ), але не так, як выключыць радок.

4

6 адказы

Што вам трэба, гэта не прагны рэгулярны выраз, але, на жаль, СЭД не дазволіць. Тым не менш, гэта можа быць зроблена ў Perl.

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

Знак пытання пасля таго, як зорачка пазначае сличитель як быць не прагнымі, таму замест таго, каб доўгая радок адпаведнасці можа знайсці, гэта зойме самае кароткую.

Надзея, што дапамагае.

Калі вы хочаце зрабіць гэта ў Perl-скрыпт, а не запускаць у камандным радку, а затым нешта накшталт гэтага будзе рабіць гэтую працу:

#! /usr/bin/perl -w
use strict; # Habit of mine
use 5.0100; # So we can use 'say'

# Save the matching expression in a variable. 
# qr// tells us it's a regex-like quote (http://perldoc.perl.org/functions/qr.html)
my $regex = qr/__(.*?)__/;

# Ordinarily, I'd write this in a way I consider to be less perl-y and more readable.
# What it's doing is reading from the filename supplied on STDIN and places the
# contents of the file in $_. Then it runs the substitution on the string, before
# printing out the result.
while (<>) {
  $_ =~ s/$regex/{{$1}}/g;
  say $_;
}

Спосаб прымянення просты:

./regex myfile
whatever{{MATCH_THIS}}whateverwhatever{{AND_THIS}}whateverwhatever

Гэта Perl, ёсць мільён і адзін спосаб зрабіць гэта!

2
дададзена
Ці з'яўляюцца ўсе SED скрыпты сумяшчальныя з Perl? Гэта значыць, калі ў мяне ёсць працоўны скрыпт патч у, я магу карміць яго Perl -pe і спадзяюся, што гэта будзе проста працаваць? Прычына, чаму я пытаюся, што я звычайна раблю рэарганізацый з СЕПГ, і ведаючы гэтага SED абмежаванні, я перайду да Perl, але я не хачу сюрпрызаў ў будучыні.
дададзена аўтар dangonfast, крыніца
Дзякуючы. Дарэчы, як я магу мець сцэнар у файле з дапамогай Perl? Што такое сцяг сказаць Perl: рэгулярны выраз у файле my.regex ?
дададзена аўтар dangonfast, крыніца
Магчыма, не адразу, не. Існуе скрыпт называецца s2p які нібыта пераўтворыць паміж імі, але я ніколі не атрымліваў гэта рабіць што-небудзь іншае, чым вырабляць памылкі! Я выкарыстоўваю СЭД для многіх PERL рэфактарынгу, як ні дзіўна!
дададзена аўтар chooban, крыніца
Я абнавіў арыгінальны адказ, каб уключыць гэта.
дададзена аўтар chooban, крыніца

GNU СЭД

sed ':k s/__/{{/;s/__/}}/;tk' file

ўваход:

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
2
дададзена

sed does not support PCRE goodies such as the non-greedy operator

Я быў у стане атрымаць вакол сітуацыі з наступным змяненнем:

echo 'whatever__MATCH_THIS__whateverwhatever__AND_THIS__whateverwhatever' |
sed -e 's/__\([^_]\+_[^_]\+\)__/\{{\1}}/g'
whatever{{MATCH_THIS}}whateverwhatever{{AND_THIS}}whateverwhatever
1
дададзена
Гэта выглядае шматабяцальным, але зірніце на гэтых ўваходных дадзеных: EXTEN => s, п, ExecIf ($ [$ {amacode} == 1] Set (rateparams_view = __ INCOMING_RATEPARAMS_VIEW __): Set (пацучыны & ZWNJ; eparams_view = __ Исходящ & ZWNJ ; ING_RATEPARAMS_VIEW_ & ZWNJ; _))
дададзена аўтар dangonfast, крыніца
@gonvaled, ах вы проста перамясцілі на ходзе гульні мне там :-). Я не ўпэўнены, што ён знаходзіцца ў межах СЕПГ 's магчымасцяў для апрацоўкі праблемы.
дададзена аўтар iruvar, крыніца

Гэта можа працаваць для вас (GNU СЭД):

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

ці, магчыма, лягчэй зразумець:

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

Адзін са спосабаў, выкарыстоўваючы патч у , хоць зразумела, што гэта не самы лепшы інструмент, каб зрабіць працу. Я пракаментаваў код, каб убачыць, што адбываецца, таму што, здаецца, крыху заблытаўся:

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}}))
1
дададзена

Гэта працуе на маім ноўтбуку 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__\}\}/
    }
    }
0
дададзена