Wie @cnicutar kommentierte, bedeutet der Rückgabecode eines Befehls, ob der Befehl erfolgreich ausgeführt wurde. hat nichts mit der Logik zu tun, die Sie in den Codes/Skripten implementiert haben.
Also, wenn Sie haben:
echo "foo"|sed '/bar/ s/a/b/'
sed gibt 0
zurück aber wenn Sie einige Syntax-/Ausdrucksfehler schreiben oder die Eingabe/Datei nicht existiert, kann sed Ihre Anfrage nicht ausführen, sed gibt 1 zurück.
Problemumgehung
das ist eigentlich kein Workaround . sed hat q
Befehl:(von der Manpage):
q [exit-code]
Hier können Sie den Exit-Code nach Belieben definieren. Zum Beispiel '/foo/!{q100}; {s/f/b/}'
wird mit Code 100 beendet, wenn foo
nicht vorhanden ist, andernfalls die Substitution f->b durchführen und mit Code 0 beenden.
Übereinstimmende Groß-/Kleinschreibung:
kent$ echo "foo" | sed '/foo/!{q100}; {s/f/b/}'
boo
kent$ echo $?
0
Nicht übereinstimmender Fall:
kent$ echo "trash" | sed '/foo/!{q100}; {s/f/b/}'
trash
kent$ echo $?
100
Ich hoffe, das beantwortet Ihre Frage.
bearbeiten
Ich muss hinzufügen, dass das obige Beispiel nur für die einzeilige Verarbeitung gilt. Deine genaue Anforderung kenne ich nicht. wenn Sie exit 1
erhalten möchten . eine Zeile ohne Übereinstimmung oder die ganze Datei. Wenn die gesamte Datei nicht übereinstimmt, können Sie awk in Betracht ziehen oder sogar grep
ausführen vor Ihrer Textverarbeitung...
Das könnte für Sie funktionieren (GNU sed):
sed '/search-string/{s//replacement-string/;h};${x;/./{x;q0};x;q1}' file
Wenn die search-string
gefunden wird, wird es durch replacement-string
ersetzt und am Dateiende sed
wird mit 0
beendet Rückgabe Code. Wenn keine Substitution stattfindet, ist der Rückgabecode 1
.
Eine genauere Erklärung:
In sed stehen dem Benutzer zwei Register zur Verfügung:der Musterraum (PS), in den die aktuelle Zeile geladen wird (abzüglich des Zeilenvorschubs), und ein Reserveregister namens Hold Space (HS), das anfänglich leer ist.
Die allgemeine Idee besteht darin, das HS als Flag zu verwenden, um anzuzeigen, ob eine Substitution stattgefunden hat. Wenn der HS am Ende der Datei noch leer ist, wurden keine Änderungen vorgenommen, ansonsten sind Änderungen aufgetreten.
Der Befehl /search-string/
stimmt mit search-string
überein mit dem, was auch immer im PS steht, und wenn gefunden wird, dass es den search-string
enthält die Befehle zwischen den folgenden geschweiften Klammern werden ausgeführt.
Zuerst die Substitution s//replacement-string/
(sed verwendet den letzten regulären Ausdruck, d.h. den search-string
, wenn die linke Seite leer ist, also s//replacement-string
ist dasselbe wie s/search-string/replacement-string/
) und danach die h
Der Befehl erstellt eine Kopie des PS und fügt sie in den HS ein.
Der sed-Befehl $
wird verwendet, um die letzte Zeile einer Datei zu erkennen, und dann geschieht Folgendes.
Zuerst die x
Der Befehl tauscht die beiden Register aus, sodass das HS zum PS und das PS zum HS wird.
Dann wird die PS nach einem beliebigen Zeichen /./
durchsucht (.
bedeutet Übereinstimmung mit einem beliebigen Zeichen) Denken Sie daran, dass der HS (jetzt der PS) zunächst leer war, bis eine Ersetzung stattfand. Wenn die Bedingung wahr ist, wird x
erneut ausgeführt, gefolgt von q0
Befehl, der die gesamte sed-Verarbeitung beendet und den Rückgabecode auf 0
setzt . Sonst die x
Befehl ausgeführt und der Rückgabecode auf 1
gesetzt .
Hinweis:obwohl der q
beendet die sed-Verarbeitung, verhindert jedoch nicht, dass der PS von sed wieder zusammengesetzt und normal gedruckt wird.
Eine weitere Alternative:
sed '/search-string/!ba;s//replacement-string/;h;:a;$!b;p;x;/./Q;Q1' file
oder:
sed '/search-string/,${s//replacement-string/;b};$q1' file
Diese Antworten sind allzu kompliziert. Was ist falsch daran, ein kleines Shell-Skript zu schreiben, das grep verwendet, um herauszufinden, ob das Ding, das Sie ersetzen möchten, vorhanden ist, und es dann mit sed ersetzt?
grep -q $TARGET_STRING $file
if [ $? -eq 0 ]
then
echo "$file contains the old site"
sed -e "s|${TARGET_STRING}|${NEW_STRING}|g" ....
fi