2013-05-19 26 views
50

Uruchamiam kilka poleceń zastępowania jako rdzeń colorize script for maven. Jedna z komend sed używa wyrażeń regularnych, które działają w powłoce jako discussed here. Bieżącą (nie działającą) implementację można znaleźć pod adresem here.Błąd sed: "Niepoprawny odnośnik 1 na komendzie RHS polecenia" s '"

Kiedy to jeden z wariantów polecenia do skryptu różnych zachowań następuje:

Wariant 1:

$ sed -re "s/([a-zA-Z0-9./\\ :-]+)/\1/g" 

dostosowany do skryptu:

-re "s/WARNING: ([a-zA-Z0-9./\\ :-]+)/${warn}WARNING: \1${c_end}/g" \ 

Błąd: Ona Wyświetli te same informacje, co gdybym wpisał $ sed. Dziwne!?


Wariant 2:

$ sed -e "s/\([a-zA-Z0-9./\\ :-]\+\)/\1/g" 

dostosowany do skryptu:

-e "s/WARNING: \([a-zA-Z0-9./\\ :-]\+\)/${warn}WARNING: \1${c_end}/g" \ 

Błąd:

sed: -e expression #7, char 59: invalid reference \1 on `s' command's RHS

+5

W moim przypadku miałem połączeniu z '-i' (zmienił w opcji miejsce) z '-re', w wyniku czego powstanie' -ire' (tak, że '-i' pochłaniało fragment' re' jako jego argument 'SUFFIX', a zatem rozszerzony tryb regex nie był włączony); zmiana go na '-i -re' rozwiązała problem. –

+0

Należy również zauważyć, że pojedyncze cudzysłowy '' 'i podwójne cudzysłowy' "są traktowane nieco inaczej, szczególnie podczas interpretacji' $ vars' .Na przykład: 'sudo sh -c 'sed -r -i' s/(^. + _supplicant.conf)/\ 1 $ {MTXT}/'/ etc/network/interfaces "' działa, ale: 'sudo sh -c' sed -r -i" s /(^.+_ supplicant.conf)/\ 1 $ {MTXT}/"/ etc/network/interfaces'' does not. – not2qubit

Odpowiedz

15

Czy naprawdę nie musisz przechwytywać, aby zadziałało? czyli dla wariantu 2:

-e "s/WARNING: (\([a-zA-Z0-9./\\ :-]\+\))/${warn}WARNING: \1${c_end}/g" \ 

(Uwaga: niesprawdzone)

+22

Opcja' -r' dla sed wydaje się być niezbędna do działania odnośnika wstecznego Np. 'Sed -e 's/([ : cyfra:]])/jest cyfrą/'' działa ale 'sed -e 's/([[: cyfra:]])/\ 1 jest cyfrą /' tworzy oryginalny błąd bez '-r' dla sed . ** UWAGA: ** pierwsze wywołanie sed szuka literału '()' i ** nie jest ** grupą przechwytującą –

+0

Komentarz poniżej odpowiedzi jest właściwie odpowiedzią. Może możesz edytować swoją odpowiedź na Odblokuj to: – miroxlav

+0

@AndrewFalanga powinieneś opublikować swój komentarz jako odpowiedź – sanmai

4

Musisz uciec / po .

sed -e "s/\([a-zA-Z0-9.\/\\ :-]\+\)/\1/g" 

A jeśli nie chcesz się martwić o ucieczce, użyj |

sed -e "s|\([a-zA-Z0-9./\\ :-]\+\)|\1|g" 

EDIT:

sed -e "s|WARNING: \([a-zA-Z0-9.-/\\ :]+\)|${warn}WARNING: \1${c_end}|g" 
+0

Brzmi rozsądnie. Ale to nie działa w kontekście skryptu. – JJD

+0

Sprawdź moją edycję, może to pomoże – slackmart

+0

Przepraszam. Edycja powoduje zwiększenie błędu: 'sed: -e expression # 7, char 58: Invalid range end'. Odpowiedź @Denis działa. – JJD

36

Ten błąd jest wspólny dla nawiasów, które nie są chronione. Ucieknij i spróbuj ponownie.


Na przykład:

/^$/b 
:loop 
$!{ 
N 
/\n$/!b loop 
} 
s/\n(.)/\1/g 

Należy uciekł z ukośniki przed każdym nawiasie:

/^$/b 
:loop 
$!{ 
N 
/\n$/!b loop 
} 
s/\n\(.\)/\1/g 
+0

Uwaga, jeśli używasz '-r', nie musisz uciekać z nawiasów. –