Ersetzen einer Zeile in mehreren Dateien

374
ayushgp

Ich habe eine Liste von Dateien und entsprechenden Zeilennummern, in denen ich die Ersetzung durchführen möchte:

s/LOG.error/LOG.warn 

Es gibt andere Stellen, an denen dies vorkommen kann und diese Leitungen nicht stören möchten. Wie mache ich das mit find und sed?

Die Datei ist wie folgt formatiert:

FooBar.java 125 FooBar.java 180 FooBar2.java 128 

Das habe ich gefunden, als ich nach einem Weg gesucht habe, dies zu tun:

cat filenames.txt | xargs sed -i '<get-line-number-here>s/LOG.error/LOG.warn' <get-file-name-here> 
0

1 Antwort auf die Frage

1
tripleee

Sie müssen die Datei nach Zieldatei in Partitionen aufteilen und sed -ijede Datei einzeln ausführen . Angenommen, Sie haben die Dateinamen und Zeilennummern nach Dateiname und in aufsteigender Reihenfolge gruppiert, Sie können so etwas tun

awk '$1 != prev { if (prev) print "\047 " prev; prev=$1; printf "sed -i \047" } { print $2 "s/LOG\\.error/LOG.warn/" } END { if (prev) print "\047 " prev }' filenames.txt | sh 

Dies ist ein schneller und schmutziger Hack, der auf interessante und möglicherweise gefährliche Art und Weise aufbricht, wenn die Dateinamen in der ersten Spalte kein einzelnes Token sind.

Grundsätzlich überarbeiten wir Ihre Textdatei in eine Folge von sedSkripten. So wird dein Beispiel in umgewandelt

sed -i '125s/LOG\.error/LOG.warn 180s/LOG\.error/LOG.warn/ ' FooBar.java sed -i '128s/LOG\.error/LOG.warn/ ' FooBar2.java 

Was Sie feststellen werden, ist ein shSkript, das sedfür jede Datei ein Skript enthält .

Wenn Sie auf einem * BSD - Plattform (einschließlich Mac OS) sind, müssen Sie ändern sed -izu sed -i ''dem in Awk wäre "sed -i \047\047", um richtig zu einfachen Anführungszeichen, ohne die umgebende Schale einbetten zu zitieren (so dass ganze Zeile wird printf "sed -i \047\047 \047" }(sic)).

Was kann ich tun, wenn ich die Datei auch zuerst im Verzeichnis finden und dann auf diesem Pfad ausführen möchte. Ich habe nicht den vollen Weg. ayushgp vor 6 Jahren 0
Ich verstehe Ihre Folgefrage nicht. Sie haben eine Datei mit Dateinamen und Zeilennummern, wissen jedoch nicht, für welche Dateien sie genau im Verzeichnisbaum gelten? Oder haben Sie eine Verzeichnisstruktur, in der ein Verzeichnis diese Datei enthalten könnte und Sie diese relativ zu diesem Verzeichnis ausführen möchten? tripleee vor 6 Jahren 0
Ich habe eine Liste von Dateien. Foobar.java zum Beispiel. Sie befindet sich irgendwo in pwd und ist die einzige Datei mit diesem Namen. In der Liste, die ich habe, habe ich nur den Namen und nicht den vollständigen Pfad zu Foobar.java. Daher möchte ich find zuerst auf diesen Namen anwenden und ihn dann an awk weitergeben, wie Sie es vorgeschlagen haben ayushgp vor 6 Jahren 0
`finden. -name Foobar.java -execdir etwas sucht die Datei und führt in diesem Verzeichnis `etwas` aus. Möglicherweise müssen Sie dies so einstellen, dass "etwas" sich nicht in welchem ​​Verzeichnis befindet, in dem Sie sich vor dem Start befunden haben (verwenden Sie den absoluten Pfad zur Eingabedatei, oder setzen Sie den Befehl möglicherweise stärker um, wenn Sie es mehr als einmal tun müssen.) zweimal). tripleee vor 6 Jahren 0
Wenn Sie dies mehr als einmal oder zweimal benötigen, überlegen Sie möglicherweise, wie Sie diese Eingabedatei überhaupt erst produzieren. tripleee vor 6 Jahren 0
Ich werde diese Datei verwenden, um diese Datei zu reproduzieren, und dann Sed verwenden, um den Vorschlag zu ersetzen ayushgp vor 6 Jahren 0