Wie ersetze ich Text zwischen zwei Markierungen in einer Datei durch einen Textabschnitt aus einer anderen Datei?

7

Angenommen, ich hatte einen Textblock in ~/.bashrc:

#~/.bashrc
# ...some commands...

# aliases
alias suicide='sudo rm -rf /'
# end aliases

# other commands

Ich möchte diesen Textblock durch einen anderen Text ersetzen, der zwischen zwei Markierungen in einer anderen Datei enthalten ist: stuff-to-place-in-bashrc.txt

# stuff-to-place-in-bashrc.txt
# ...stuff...

# aliases
alias ldir='ls * -d'
alias ithinklifeisworthliving='echo all good'
# end aliases

# ...more stuff...

ich habe es versucht

 sed -ne 's/# aliases\s+\(.*\)\s+# end aliases/\1/' stuff-to-place-in-bashrc.txt

Aber ich schwinge hier wirklich im Dunkeln. Könnte mir jemand helfen?

  1. Wie extrahiere ich den Text aus dem stuff-to-place-in-bashrc.txt?

  2. Wie ersetze ich den anderen Abschnitt ~/.bashrcdurch den extrahierten Text aus Frage 1?

Bearbeiten

Vielen Dank für die Updates, Leute, die sich fragen, warum ich so etwas möchte:

Ermöglicht ausgewählte Aktualisierungen von Skriptdateien, ohne benutzerdefinierte Ergänzungen zu überschreiben. nützlich für gemeinsam genutzte und häufig aktualisierte Standardbetriebsumgebungen (wie mein letzter Job bei Tyro , der mit XP codiert wurde).

verrückt werden Jungs.

thenaglecode
quelle
Siehe auch Text zwischen geschweiften Klammern in der vorverarbeiteten C-Datei erfassen . Ändern Sie "geschweifte Klammern" mit Ihren Anfangs- und Endmarken ( # aliasesund # end aliases), und es kann für Sie funktionieren.

Antworten:

9

Ed ist der Standardeditor, da Sie damit Ed-Skripte entwickeln und seine Arbeit, wie Sie zuvor getestet haben, interaktiv ausführen können. Für kleine Dateien wie .bashrcoder jeden Codetext ist ed performant, da es die gesamte Datei in einem Ansturm liest und mit dem Puffer arbeitet. Aus dem gleichen Grund sollten Sie ed nicht für große Dateien wie Protokolldateien verwenden.

Aber mit einem ed-Skript ist Ihre Arbeit in kürzester Zeit erledigt:

ed ~/.bashrc<<EOF
/^# aliases
+,/^# end aliases/-1d
-r !sed -n '/^# aliases/,/^# end aliases/p' stuff-to-place-in-bashrc.txt|grep -v '^#'
w
q
EOF

Ich verwende ähnliche Skripte, um Konfigurationsdateien automatisch zu optimieren, z. B. .asoundrc für verschiedene Umgebungen, in die ich meinen Laptop bringe.

Das beste Dokument über ed ist eine einfache Handbuchseite aus dem sehr coolen PLAN9- System. Ich habe es in ein ed.ps- Postscript-Dokument übersetzt. Wenn Sie an PLAN9 interessiert sind , sollten Sie 9front und http://cat-v.org/ überprüfen, da die ursprüngliche Bell Labs-Version weiterhin beibehalten wird, aber über ein sehr einfaches Dateisystem verfügt.

Ein letztes Wort zu Editor Wars, Emacs, Vim und dergleichen: Acme Rules!

ikrabbe
quelle
Vielen Dank für die Antwort. Es hat funktioniert, aber ich bin mir nicht sicher, wie die Syntax lautet. Verwendet es Regex oder etwas Spezifischeres für ed? sieht aus wie es vim wie Befehle gibt ( w, q)
thenaglecode
Es werden reguläre Ausdrücke ( /^# aliases, und /^# end aliases/) verwendet, und die anderen Befehle sind Vi / Ed. Siehe z. B. vimhelp.appspot.com/cmdline.txt.html#%3Arange für +, /^# end aliases/.
Muru
1
siehe info Edauf Ihrem System (hoffentlich). Ich weiß nicht, warum moderne Linux-Distributionen diesen coolen Editor nicht installieren. w und q sind Schreib- und Beendigungsbefehle. Und ed funktioniert sehr ähnlich wie sed mit Regexen. Es gibt einen Grund, warum die Namen so ähnlich klingen. d bedeutet, dass die adressierten Zeilen gelöscht werden. -r liest die Ergebnisse des !folgenden Befehls in die vorherige Zeile ein . Ich verkürze die Dateinamen in der Bearbeitung, da ich heute früh so faul schreibe.
Ikrabbe
1
@thenaglecode siehe meine letzte Bearbeitung. Ich musste das testen, bevor ich es veröffentlichte.
Ikrabbe
1
@thenaglecode Die einzige wirklich gute Seite über ed, die ich jemals brauchte, war die ed (1) -Seite von plan9: man.cat-v.org/plan_9/1/ed Ich kann Ihnen eine Postscript-Version senden, wenn Sie möchten . Da es sich nur um plan9 handelt, lesen Sie auch den acme-Editor. Wenn Sie sich daran gewöhnen, werden Sie nie etwas anderes verwenden. Natürlich ist es am besten, ein plan9-System zu verwenden, beispielsweise als virtuelle Maschine in Ihrer Linux-Box, aber der p9p-Port für Unix ist auch großartig. (Es gibt kleine Unterschiede zwischen plan9 ed und gnu ed!)
ikrabbe
2
set /^\#aliases/  /^\#end\ aliases/
sed -ne"$1,$2"'s/\\\{0,1\}/&&/gp' <stuff_to_place...rc |
sed -e"$1,$2c\" -f- ./infile >./outfile

Wenn Sie die Datei direkt bearbeiten möchten, edist dies eine sehr gute Lösung. Wenn Sie es im Stream bearbeiten möchten, verwenden Sie sed. Vermeiden Sie sed -i.

mikeserv
quelle
0

Sicher, Sie können dies edalleine tun , ohne zusätzliche Tools zu benötigen:

ed -s stuff_to_place.txt<<\IN
1,/# aliases/d
/# end aliases/,$d
,d
.r /home/username/.bashrc
/# aliases/x
.t.
.,/# end aliases/-d
,p
q
IN

Wenn Sie mit dem Ergebnis zufrieden sind, ersetzen Sie es ,pdurch w /home/username/.bashrc, um die Änderungen in zu schreiben ~/.bashrc(beachten Sie den vollständigen Pfad, der mit rund verwendet wird w; Sie können ihn einfach verwenden, .bashrcwenn er vorhanden ist cwd).
So funktioniert das: Wir dlöschen zuerst die nicht benötigten Zeilen aus stuff_to_place.txt. Dann löschen wir die restlichen (die Aliase) mit ,d. Der Textpuffer ist jetzt leer, während der Schnittpuffer die gewünschten Zeilen enthält. Wir rlesen dann den Inhalt von .bashrcin den Textpuffer , setzen den Inhalt des Ausschneidepuffers ( x) hinter die /# aliases/Zeile, duplizieren die zuletzt eingefügte Zeile ( .t.) und löschen sie aus der duplizierten Zeile bis einschließlich, aber nicht einschließlich /# end aliases/und schließlich print oder write Änderungen und quit.

don_crissti
quelle