Ich versuche, mit SED Text aus einer Protokolldatei zu extrahieren. Ich kann ohne allzu große Probleme suchen und ersetzen:
sed 's/foo/bar/' mylog.txt
Ich möchte jedoch die Suche unabhängig von Groß- und Kleinschreibung machen. Nach dem, was ich gegoogelt habe, sollte das Anhängen i
an das Ende des Befehls funktionieren:
sed 's/foo/bar/i' mylog.txt
Dies gibt mir jedoch eine Fehlermeldung:
sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'
Was läuft hier falsch und wie behebe ich das?
macos
replace
sed
case-insensitive
Craig Walker
quelle
quelle
I
ist eine GNU-Erweiterung, die mit Ihrer Kopie von sed möglicherweise nicht verfügbar ist.man sed
Ist mit der Implementierung konsistent - keine Erwähnung (und in der Praxis keine Unterstützung) für Matching ohne Berücksichtigung der Groß- und Kleinschreibung; Wenn Sie eine Dokumentation gefunden haben, die etwas anderes behauptet, teilen Sie uns dies bitte mit.g
Präfix installiert , damit ich sie verwenden kanngsed
odergdate
wenn ich eine Funktion benötige, die in der Standardversion nicht enthalten ist.Antworten:
Um es klar auszudrücken : Unter macOS - ab Mojave (10.14) -
sed
- was die BSD- Implementierung ist - wird das Matching ohne Berücksichtigung der Groß- und Kleinschreibung NICHT unterstützt - kaum zu glauben, aber wahr. Die zuvor akzeptierte Antwort , die selbst einen GNU-sed
Befehl anzeigt , erhielt diesen Status aufgrund derperl
in den Kommentaren erwähnten basierenden Lösung.Verwenden Sie Folgendes, damit diese Perl-Lösung auch mit Fremdzeichen über UTF-8 funktioniert :
-C
Aktiviert die UTF-8-Unterstützung für Streams und Dateien, vorausgesetzt, das aktuelle Gebietsschema basiert auf UTF-8.-Mutf8
weist Perl an, den Quellcode als UTF-8 zu interpretieren (in diesem Fall die übergebene Zeichenfolge-pe
) - dies ist das kürzere Äquivalent des ausführlicheren-e 'use utf8;'.
Dankes, Mark Reed(Beachten Sie, dass die Verwendung ebenfalls
awk
keine Option ist , daawk
unter macOS (dh BWK awk , auch bekannt als BSD awk ) die Gebietsschemas anscheinend überhaupt nicht bekannt sind - seinetolower()
undtoupper()
Funktionen ignorieren Fremdzeichen (undsub()
/ odergsub()
haben keine Groß- / Kleinschreibung-Flags) anfangen mit).)quelle
Anmerkung des Herausgebers : Diese Lösung funktioniert nicht unter macOS (sofort einsatzbereit), da sie nur für GNU gilt
sed
, während macOS mit BSD geliefert wirdsed
.Großschreibe das Ich.
quelle
I
Suffix ist keine tragbare Verwendung vonsed
. POSIXsed
verwendet nur Basic Regular Expressions (BREs), die überraschend begrenzt sind. Sie unterstützen nicht einmal das+
(Sie müssen\{1,\}
stattdessen verwenden), geschweige denn das Matching ohne Berücksichtigung der Groß- und Kleinschreibung. Die einzige tragbare Möglichkeit, dies mit sed zu tun, besteht darin, nach etwas Ähnlichem/[hH][eE][lL][lL][oO]/
zu suchen, was oft unpraktisch sein wird./gI
dass es nur beim ersten Spiel funktioniert.Eine weitere Lösung für
sed
Mac OS X besteht darin,gsed
MacPorts oder HomeBrew zu installieren und anschließend den Alias zu erstellensed='gsed'
.quelle
brew install gnu-sed
ging dann zu meinem ~ / .bash_profile und fügte den Alias hinzu. Danke @davmatbrew install gnu-sed --with-default-names
- dies überschreibt die Standardeinstellungsed
.Die sed FAQ befasst sich mit der eng verwandten Suche ohne Berücksichtigung der Groß- und Kleinschreibung . Es wird darauf hingewiesen, dass a) viele Versionen von sed eine Flagge dafür unterstützen und b) es in sed umständlich ist, lieber awk oder Perl zu verwenden.
Um dies in POSIX sed zu tun, schlagen sie drei Optionen vor (hier für die Substitution angepasst):
In Großbuchstaben konvertieren und ursprüngliche Zeile im Haltebereich speichern; Dies funktioniert jedoch nicht für Ersetzungen, da der ursprüngliche Inhalt vor dem Drucken wiederhergestellt wird. Daher eignet es sich nur zum Einfügen oder Hinzufügen von Zeilen, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird.
Vielleicht sind die Möglichkeiten beschränkt zu sein
FOO
,Foo
undfoo
. Diese können abgedeckt werden durchUm nach allen möglichen Übereinstimmungen zu suchen, kann man für jedes Zeichen Klammerausdrücke verwenden:
quelle
Die Mac-Version von
sed
scheint etwas eingeschränkt zu sein. Eine Möglichkeit, dies zu umgehen, besteht darin, einen Linux-Container (über Docker) zu verwenden, der eine verwendbare Version vonsed
:quelle
Wenn Sie zuerst einen Mustervergleich durchführen, z.
dann möchten Sie das
I
nach dem Muster setzen:Beispiel:
kehrt zurück
willma
; ohne dasI
gibt es den String unberührt zurück (Fred
).quelle
sed: 1: "/fred/Is//willma/g": invalid command code I
sed -r '/'"$PATTERN"'/I,${s//'$YELLOW'&'$NO_COLOR'/g;b};$q3'
. Der Text wird gedruckt, und wenn ein Muster (ohne Berücksichtigung der Groß- und Kleinschreibung) gefunden wurde, wird der Text in Gelb (Ansi-Farbe) hervorgehoben. Wenn nicht gefunden - gibt den Exit-Code 3 zurück.Ich hatte ein ähnliches Bedürfnis und kam auf folgendes:
Dieser Befehl, um einfach alle Dateien zu finden:
Um this_shell.sh auszuschließen (falls Sie den Befehl in ein Skript namens this_shell.sh einfügen ), senden Sie die Ausgabe an die Konsole, um zu sehen, was passiert ist, und verwenden Sie dann sed für jeden gefundenen Dateinamen, um den Text foo durch bar zu ersetzen ::
Ich habe mich für diese Methode entschieden, da mir nicht gefallen hat, dass alle Zeitstempel für nicht geänderte Dateien geändert wurden. Wenn Sie das grep-Ergebnis eingeben, können nur die Dateien mit dem Zieltext angezeigt werden (dies kann wahrscheinlich auch die Leistung / Geschwindigkeit verbessern).
Stellen Sie sicher, dass Sie Ihre Dateien sichern und testen, bevor Sie sie verwenden. Funktioniert in einigen Umgebungen möglicherweise nicht für Dateien mit eingebetteten Leerzeichen. (?)
quelle
Verwenden Sie Folgendes, um alle Vorkommen zu ersetzen: sed 's / foo / bar / gI' mylog.txt
quelle
I
. Ich denke auch nicht, dass dies die Frage wirklich beantwortet, da es nicht um globalen Ersatz geht.