Wie kann ich einen Teil einer Textdatei zwischen Markierungen durch eine andere Textdatei ersetzen?

18215
smokris

Angenommen, ich habe eine Textdatei wie diese:

# custom content section a b  ### BEGIN GENERATED CONTENT c d ### END GENERATED CONTENT 

Ich möchte den Teil zwischen den GENERATED CONTENTTags durch den Inhalt einer anderen Datei ersetzen .

Was ist der einfachste Weg, dies zu tun?

22

4 Antworten auf die Frage

30
Peter.O
lead='^### BEGIN GENERATED CONTENT$' tail='^### END GENERATED CONTENT$' sed -e "/$lead/,/$tail/{ /$lead/; /$tail/p; d }" existing_file 
Ausgezeichnet. `sed` kann so viel mehr als nur` s / ... / ... `! DevSolar vor 11 Jahren 0
Hmmm funktioniert bei mir nicht, sollte ich den sed-Befehl auf eine Zeile setzen? lzap vor 9 Jahren 0
Der Befehl `r insert_file` muss das letzte in seiner Zeile sein. * Beachten Sie *, dass danach weder Leerzeichen noch Kommentare zulässig sind. Der Code wurde mit GNU `sed` mit aktivierter` --posix`-Option getestet und funktionierte wie erwartet. Daher sollte er mit jedem * posix-kompatiblen * `sed` funktionieren. Peter.O vor 9 Jahren 3
Heiliger Moly, das ist cool! Das ist in meinem sed Wörterbuch! Sehr nützlich und schön einfach. Vielen Dank! DanielSmedegaardBuus vor 9 Jahren 1
Beachten Sie, dass eine Bearbeitung vor Ort erforderlich ist, wenn Sie die Ausgabe von sed erfassen (z. B. `output = $ (sed -e" ... "bestehende_Datei)`) und dann die Ersetzung in einem zweiten Durchlauf durchführen (z. B. `echo" $ output ">) exists_file`), da der Versuch, in eine Datei umzuleiten, die Sie lesen, dazu führt, dass sie abgeschnitten wird, bevor der Inhalt gelesen wird. Chris Tonkinson vor 7 Jahren 2
4
Dr Kitty

Warnung: Dies ist definitiv nicht die einfachste Möglichkeit, dies zu tun. (EDIT: bash funktioniert; POSIX grep ist auch in Ordnung)

Wenn der Haupttext in der Datei "main" und der generierte Inhalt in der Datei "gen" enthalten ist, können Sie Folgendes tun:

#!/bin/bash BEGIN_GEN=$(cat main | grep -n '### BEGIN GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g') END_GEN=$(cat main | grep -n '### END GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g') cat <(head -n $(expr $BEGIN_GEN - 1) main) gen <(tail -n +$(expr $END_GEN + 1) main) >temp mv temp main 
Funktioniert das? Ich denke, Ihre letzte Zeile wird "main" zum Schreiben öffnen, löschen, bevor sie von cat gelesen wird. chepner vor 11 Jahren 0
@chepner Mist, du hast recht. Der Rest funktioniert aber. Ich werde es reparieren. Dr Kitty vor 11 Jahren 0
4
smokris
newContent=`cat new_file` perl -0777 -i -pe "s/(### BEGIN GENERATED CONTENT\\n).*(\\n### END GENERATED CONTENT)/\$1$newContent\$2/s" existing_file 
Gut gemacht. Viel einfacher als meiner. :) Dr Kitty vor 11 Jahren 0
1
Jetchisel
ed -s FILE1 <<EOF /### BEGIN GENERATED/+,/### END GENERATED/-d /### BEGIN GENERATED/ r FILE2 w q EOF 
Verwendung eines Heredocs und des Ed-Zeileneditors. Die erste Zeile innerhalb des Heredocs besteht darin, 'd' die Zeile nach '+' der '### BEGIN GENERATED ...' und die Zeile vor '-' der '### END GENERATED ...' der zweiten Zeile zu löschen fügt FILE2 nach der Zeile ein ### END GENERATED ... ' Jetchisel vor 9 Jahren 0
Entschuldigung, was ich meinte, war FILE2 hinter der Zeile "### BEGIN GENERATED ..". Jetchisel vor 9 Jahren 0
Nimm es ruhig mit mir, es ist immerhin mein erstes Mal :-). Ich habe das Wort vielleicht auch gleich verwendet, aber die andere Lösung verwendet keine Heredocs, sondern eine Printf und eine Pipe. Wie auch immer, entschuldige mich, wenn ich einen Fehler gemacht habe :-) Jetchisel vor 9 Jahren 0