Im Grunde möchte ich nur die Ausgaben ändern, wenn die Eingabe einem Filter entspricht, aber der geänderte Teil nicht das ist, was gefiltert wird (sonst würde ich verwenden sed
). Das Problem besteht bisher darin, dass mein awk
nur die geänderten Zeilen ausgibt.
Kurzes Beispiel, fügen Sie dies in test.txt ein:
orange beet pear cowmilk
apple pear berry cowmilk
orange melon cherry cowmilk
Wenn ich den Code verwende:
awk /orange/'{gsub(/cow/,"cow~"); print}' test.txt
Ich bekomme:
orange beet pear cow~milk
orange melon cherry cow~milk
Wann ich lieber hätte:
orange beet pear cow~milk
apple pear berry cowmilk
orange melon cherry cow~milk
Ich sehe, dass es mit awk geht ||
, habe aber nicht herausgefunden, wie ich es mit dem obigen gsub kompatibel mache.
Als Bonus-Anerkennung würde ich wirklich gerne Farbe anstelle von hinzufügen ~
, aber das bricht völlig zusammen, d. h.
awk /orange/'{gsub(/cow/,"cow'\e[1;34m'"); print}' test.txt
gibt mir einen Fehler aus, dass \
es sich nicht um das Ende der Zeile handelt.
Antwort1
Für die Farbe müssen Sie das eigentliche ESC-Zeichen angeben (nicht die Escape-Form \e
). Der Wert ist hexadezimal \x1B
oder oktal \033
. Die folgenden Skripte färben den Bindestrich -
und drucken alle Eingabezeilen
awk '/orange/{gsub(/cowmilk/,"cow\x1B[1;34m-\x1B[0mmilk")} {print}' "$file"
sed '/orange/{s/cowmilk/cow\x1B[1;34m-\x1B[0mmilk/g}' "$file"
Antwort2
Um alle Zeilen nach der Änderung einiger weniger auszudrucken, fügen Sie eine separate Bedingung hinzu, die immer als „true“ ausgewertet wird, etwa ( 1
):
awk '/orange/{gsub("cow", "cow~")} 1' "$file"
Sie könnten auch {print}
explizit Folgendes angeben:
awk '/orange/{gsub("cow", "cow~")} {print}' "$file"
Denken Sie daran, dass jede awk-Anweisung aus einer Bedingung und einer Anweisungsklausel besteht:
condition {statements}
Aber jedes davon ist optional, wenn Sie nicht einschließen{statements}
, dann {print}
wird verwendet. Wenn Sie nicht einschließencondition
, dann 1
wird verwendet.