błąd sed: „nieprawidłowe odniesienie \ 1 na prawej stronie komendy` s '”

104

Uruchamiam kilka poleceń zastępowania jako rdzeń skryptu kolorowania dla maven . Jedno z sedpoleceń używa wyrażenia regularnego, które działa w powłoce, jak omówiono tutaj . Aktualną (nie działającą) implementację można znaleźć tutaj .

Kiedy dołączam jeden z wariantów polecenia do skryptu, zachodzi się inaczej:

Wariant 1:

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

Dostosowane do scenariusza:

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

Błąd: Powłoka wyświetla te same informacje, co gdybym wpisał $ sed. Dziwne!?


Wariant 2:

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

Dostosowane do scenariusza:

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

Błąd:

sed: -e wyrażenie # 7, char 59: niepoprawne odniesienie \ 1 do prawej strony polecenia `s '

JJD
źródło
10
W moim przypadku połączyłem -iopcję (edit in place) z -re, co spowodowało -ire(tak, że -izużywał refragment jako jego SUFFIXargument, a zatem rozszerzony tryb regex nie był włączony); zmieniając go, aby -i -rerozwiązać problem.
Janaka Bandara
Warto również zauważyć, że apostrofy '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'nie.
not2qubit

Odpowiedzi:

52

Czy nie musisz faktycznie rejestrować, aby to zadziałało? tj. dla wariantu 2:

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

(Uwaga: nieprzetestowane)

Bez argumentu -r odniesienia wsteczne (takie jak \ 1) nie będą działać.

Denis de Bernardy
źródło
42
-rOpcja pojawi sed być konieczne do tylnej odniesieniu do pracy. Np. sed -e 's/([[:digit:]])/is a digit/'Działa, ale sed -e 's/([[:digit:]])/\1 is a digit/generuje oryginalny błąd bez -rseda. UWAGA: pierwsze wywołanie sed wyszukuje literał (<digit>)i nie jest grupą przechwytywania.
Andrew Falanga
Komentarz pod odpowiedzią jest w rzeczywistości odpowiedzią. Może możesz zmodyfikować swoją odpowiedź, aby ją odzwierciedlić.
miroxlav
@AndrewFalanga powinieneś był opublikować swój komentarz jako odpowiedź
sanmai
2
Nieważne, moim błędem było używanie -irezamiast używania -ri. Porządek ma znaczenie :-)
m3nda
54

Ten błąd występuje często w przypadku nawiasów bez zmiany znaczenia. Ucieknij im i spróbuj ponownie.


Na przykład:

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

Przed każdym nawiasem należy używać odwrotnych ukośników:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g
e18r
źródło
6
Uwaga, jeśli używasz -r, nie musisz uciekać przed nawiasami.
qräbnö
13

Jeśli opcja -r/ --regexp-extendednie jest podana, należy wprowadzić zmiany w nawiasach przechwytujących.

OrangeDog
źródło
5

Musisz uciec /po.

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

Lub jeśli nie chcesz się martwić o ucieczkę, użyj |

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

EDYTOWAĆ:

sed -e "s|WARNING: \([a-zA-Z0-9.-/\\ :]+\)|${warn}WARNING: \1${c_end}|g"
slackmart
źródło
Brzmi rozsądnie. Ale to nie działa w kontekście scenariusza.
JJD
Przepraszam. Edit podnosi błąd: sed: -e expression #7, char 58: Invalid range end. Odpowiedź @Denisa działa.
JJD
2
Ok, a potem +1 dla odpowiedzi
@Denis