it-swarm.com.de

Verwenden von sed und grep/egrep zum Suchen und Ersetzen

Ich verwende egrep -R, gefolgt von einem regulären Ausdruck, der ungefähr 10 Vereinigungen enthält, also: .jpg | .png | .gif usw. Dies funktioniert gut, jetzt möchte ich alle gefundenen Zeichenfolgen mit .bmp ersetzen.

Ich dachte an so etwas

egrep -lR "\.jpg|\.png|\.gif" . | sed "s/some_expression/.jpg/" file_it_came_form

daher geht es hier darum, wie ich einen ähnlichen Union-regulären Ausdruck in sed mache, und wie sage ich es, um die Änderungen an der Datei zu speichern, aus der die Eingabe stammt.

93
Ori

Verwenden Sie diesen Befehl:

egrep -lRZ "\.jpg|\.png|\.gif" . \
    | xargs -0 -l sed -i -e 's/\.jpg\|\.gif\|\.png/.bmp/g'
  • egrep: Suche nach übereinstimmenden Zeilen mit erweiterten regulären Ausdrücken

    • -l: listet nur Dateinamen auf

    • -R: rekursiv durch alle angegebenen Verzeichnisse suchen

    • -Z: Verwenden Sie \0 als Datensatztrennzeichen

    • "\.jpg|\.png|\.gif": stimmt mit einer der Zeichenfolgen ".jpg", ".gif" oder ".png" überein

    • .: Startet die Suche im aktuellen Verzeichnis

  • xargs: Führt einen Befehl mit der Standardeinstellung als Argument aus

    • -0: Verwenden Sie \0 als Datensatztrennzeichen. Dies ist wichtig, um den -Z von egrep abzugleichen und um nicht durch Leerzeichen und Zeilenumbrüche in Eingabedateinamen getäuscht zu werden.

    • -l: Verwenden Sie eine Zeile pro Befehl als Parameter

  • sed: der s tream ed itor

    • -i: Ersetzen Sie die Eingabedatei durch die Ausgabe, ohne eine Sicherung durchzuführen

    • -e: Verwenden Sie das folgende Argument als Ausdruck

    • 's/\.jpg\|\.gif\|\.png/.bmp/g': Ersetzen Sie alle Vorkommen der Zeichenfolgen ".jpg", ".gif" oder ".png" durch ".bmp".

178
David Schmitt

Ehrlich gesagt, so sehr ich auch Sed für geeignete Aufgaben liebe, ist dies definitiv eine Aufgabe für Perl - es ist wirklich mächtiger für diese Art von One-Liner, vor allem, wenn man es "zurückschreibt, wo es herkommt" (der -i-Schalter von Perl macht es für Sie, und optional können Sie auch die alte Version beibehalten, z. B. mit einer .bak-Datei. Verwenden Sie stattdessen -i.bak.

Perl -i.bak -pe 's/\.jpg|\.png|\.gif/.jpg/

anstelle komplizierter Arbeiten in sed (wenn überhaupt möglich) oder awk ...

11
Alex Martelli

Eine andere Möglichkeit, dies zu tun 

find . -name *.xml -exec sed -i "s/4.6.0-SNAPSHOT/5.0.0-SNAPSHOT/" {} \;

Hilfe zum obigen Befehl

Der Suchvorgang wird für Sie in dem aktuellen Verzeichnis durchgeführt, das mit . angegeben ist.

-name Der Name der Datei kann in meinem Fall mit pom.xml Platzhalter geben.

-exec ausführen

sed Stream-Editor

-i Fall ignorieren

s steht für Ersatz

/4.6.0.../ Zeichenfolge, die durchsucht werden soll

/5.0.0.../ Zeichenfolge, die ersetzt werden soll

9
Cyril Cherian

Ich konnte keinen Befehl auf dieser Seite für mich erhalten: Die sed-Lösung fügte am Ende aller verarbeiteten Dateien eine neue Zeile hinzu und die Perl-Lösung konnte nicht genug akzeptieren Argumente von find. Ich habe diese Lösung gefunden, die perfekt funktioniert:

find . -type f -name '*.[hm]' -print0 
    | xargs -0 Perl -pi -e 's/search_regex/replacement_string/g'

Dadurch wird die aktuelle Verzeichnisstruktur wiederhergestellt und in allen Dateien, die auf search_regex oder replacement_string enden, .h durch .m ersetzt.

Ich habe auch rpl für diesen Zweck in der Vergangenheit verwendet.

5
titaniumdecoy

Mein Anwendungsfall war, dass ich foo:/Drive_Letter durch foo:/bar/baz/xyz.__ ersetzen wollte. In meinem Fall konnte ich dies mit dem folgenden Code tun .

find . -name "*.library" -print0 | xargs -0 sed -i '' -e 's/foo:\/Drive_Letter:/foo:\/bar\/baz\/xyz/g'

hoffe das hat geholfen.

UPDATE S | foo:/Laufwerksbuchstabe: | foo:/ba/baz/xyz | g 

0
neo7

probiere etwas mit einer for-Schleife

 for i in `egrep -lR "YOURSEARCH" .` ; do echo  $i; sed 's/f/k/' <$i >/tmp/`basename $i`; mv /tmp/`basename $i` $i; done

nicht hübsch, sollte aber tun.

0
Don Johe