sed error: "Ungültige Referenz \ 1 auf der RHS des Befehls" s "

103

Ich führe mehrere Substitutionsbefehle als Kern eines Kolorierungsskripts für Maven aus . Einer der sedBefehle verwendet einen regulären Ausdruck, der wie hier beschrieben in der Shell gefunden wird . Die aktuelle (nicht funktionierende) Implementierung finden Sie hier .

Wenn ich eine der Varianten des Befehls in das Skript einbinde, tritt ein anderes Verhalten auf:

Variante 1:

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

An das Skript angepasst:

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

Fehler: Die Shell gibt die gleichen Informationen aus, als würde ich tippen $ sed. Seltsam!?


Variante 2:

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

An das Skript angepasst:

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

Error:

sed: -e Ausdruck # 7, char 59: ungültige Referenz \ 1 auf der RHS des Befehls 's'

JJD
quelle
10
In meinem Fall hatte ich eine -i(Option zum Bearbeiten an Ort und Stelle) mit kombiniert -re, was dazu führte -ire(dass -idas reFragment als SUFFIXArgument verwendet wurde und daher der erweiterte Regex-Modus nicht aktiviert wurde). Ändern Sie es, um -i -redas Problem zu beheben.
Janaka Bandara
Es ist auch zu beachten, dass einfache 'und doppelte Anführungszeichen "leicht unterschiedlich behandelt werden, insbesondere beim Dolmetschen $vars. Zum Beispiel: sudo sh -c "sed -r -i 's/(^.+_supplicant.conf)/\1${MTXT}/' /etc/network/interfaces"funktioniert, aber: sudo sh -c 'sed -r -i "s/(^.+_supplicant.conf)/\1${MTXT}/" /etc/network/interfaces'nicht.
not2qubit

Antworten:

51

Müssen Sie nicht tatsächlich erfassen, damit das funktioniert? dh für Variante 2:

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

(Hinweis: ungetestet)

Ohne das Argument -r funktionieren Rückverweise (wie \ 1) nicht.

Denis de Bernardy
quelle
42
Die -rOption zum Sedieren scheint notwendig zu sein, damit der Rückverweis funktioniert. ZB sed -e 's/([[:digit:]])/is a digit/'funktioniert aber sed -e 's/([[:digit:]])/\1 is a digit/erzeugt den ursprünglichen Fehler ohne -rzu sedieren. HINWEIS: Der erste Aufruf von sed sucht nach einem Literal (<digit>)und ist keine Erfassungsgruppe.
Andrew Falanga
Der Kommentar unter der Antwort ist eigentlich eine Antwort. Vielleicht können Sie Ihre Antwort bearbeiten, um sie wiederzugeben.
Miroxlav
@ AndrewFalanga Sie sollten Ihren Kommentar als Antwort gepostet haben
Sanmai
2
Trotzdem war mein Fehler, zu verwenden -irestatt zu verwenden -ri.
Bestellangelegenheiten
54

Dieser Fehler tritt häufig bei Klammern auf, die nicht maskiert werden. Entkomme ihnen und versuche es erneut.


Beispielsweise:

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

Sollte vor jeder Klammer mit Backslashes versehen werden:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g
e18r
quelle
6
Achtung, wenn Sie verwenden, müssen -rSie den Klammern nicht entkommen.
Qräbnö
13

Wenn die Option -r/ --regexp-extendednicht angegeben ist, müssen die Erfassungsklammern maskiert werden.

OrangeDog
quelle
5

Sie müssen /nach dem entkommen.

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

Oder wenn Sie sich keine Sorgen um die Flucht machen möchten, verwenden Sie |

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

BEARBEITEN:

sed -e "s|WARNING: \([a-zA-Z0-9.-/\\ :]+\)|${warn}WARNING: \1${c_end}|g"
Slackmart
quelle
Klingt vernünftig. Im Kontext des Skripts funktioniert dies jedoch nicht.
JJD
Es tut uns leid. Die Bearbeitung löst den Fehler aus : sed: -e expression #7, char 58: Invalid range end. Die Antwort von @Denis funktioniert.
JJD
2
Ok, dann +1 für @Denis 'Antwort
Slackmart