Der schnellste Weg, eine Zeile in einer Textdatei vor eine andere Zeile in einer Textdatei zu verschieben?

7

Ich habe die Zeilennummer 55 in einer Textdatei, die ich kurz vor der Zeilennummer 23 in derselben Textdatei verschieben möchte. Ich weiß, dass Sie Zeilen um eine bestimmte Anzahl von Zeilen 1 , 2 nach oben verschieben können, aber ist es möglich, eine Zeile an eine andere Zeile anzuhängen oder voranzustellen, anstatt die Zeilen ausführlich nach oben oder unten in einer Textdatei zu verschieben?

Ich bin offen für Antworten mit vim, sed oder einem anderen Befehlszeilenprogramm, aber je prägnanter, desto besser

aktualisieren:

Der sedBefehl ifügt Text vor einer Zeile ein, die dem ähnelt, wonach ich suche, außer dass ich eine Zeile vor einer Zeile einfügen möchte

MyWrathAcademia
quelle
Beide genannten Links haben Lösungen von ed, haben Sie sie ausprobiert?
RomanPerekhrest
@ RomanPerekhrest, ich bin nicht vertraut, edaber ich habe diese Lösungen auch verpasst, weil ich nicht weit genug nach unten
gescrollt
Vielleicht möchten Sie sich bei Vi und Vim Stack Exchange nach Fragen zu Vim umsehen!
Filbranden

Antworten:

11

Ein skriptfähiger Editor macht dies ziemlich einfach!

printf '%s\n' '55m22' 'wq' | ed -s input

Dies sendet zwei Befehle an ed(Bearbeiten der benannten Datei input):

  1. 55m22 - Zeile 55 nach Zeile 22 verschieben
  2. wq - Speichern Sie die Datei wieder auf der Festplatte und beenden Sie sie.
Jeff Schaller
quelle
Es hat fast perfekt funktioniert, aber ich habe Ihre Antwort nicht vollständig gelesen, also hat es Zeile 55 nach Zeile 22 verschoben, was keine große Sache ist, nur etwas, das Sie beachten sollten. Was den von Ihnen geposteten Befehl betrifft: Warum haben Sie die beiden Befehle mit einem Zeilenumbruch getrennt? Normalerweise empfängt der zweite Befehl, der mit dem Ende der Pipe verbunden ist, die Ausgabe der Pipe als eine Reihe von Argumenten, z Ein Verzeichnis, das Verzeichnis1 und Verzeichnis2 enthält, echo * | ls -lentspricht ls -l directory1 directory2. Warum nicht printf '%s ' '55m22' 'wq' | ed -s input'?
MyWrathAcademia
@MyWrathAcademia So funktionieren Rohre nicht und auch nicht ls. Das Wort Aufteilen wird normalerweise nur von der Shell durchgeführt, aber die Shell ändert nicht, was in die Pipe gelangt. Pipes übertragen Rohdaten, es ist Sache des Zielprogramms, was damit zu tun ist. Wenn Sie edeinen Befehl pro Zeile erwarten, müssen Sie diesen angeben.
Frostschutz
Ich habe verwendet, 22weil der mBefehl ove die adressierte Zeile nach der Zielzeile verschiebt und Sie wollten, dass sie vor der Zeile landet 23.
Jeff Schaller
@frostschutz, danke für die Korrektur, kannst du angeben, welcher Teil meiner Rohrbeschreibung falsch informiert wurde? Geht es um eine Reihe von Argumenten oder um den Befehl, nachdem die Pipe mit dem Ende der Pipe verbunden wurde? Was die "Wortaufteilung, die nur von der Shell durchgeführt wird" betrifft, ist nicht der Befehlszeilenbenutzer derjenige, der die Wortaufteilung in die Shell in Form von \n(Zeilenvorschub), `` (Leerzeichen), \r(Wagenrücklauf ) angibt ) usw.?
MyWrathAcademia
1
Der Zeilenumbruch, den Sie im printfFormat sehen, sendet die Befehle mit einer neuen Zeile, sodass edsie als zwei separate Befehle angezeigt werden, als ob Sie edinteraktiv ausgeführt hätten.
Jeff Schaller
4

Etwas kürzer:

ex input <<<"55m22|wq"
Steve
quelle
Wenn Sie von dieser Shell-Unterstützung ausgehen, können Sie auch schreiben ed -s input <<< $'55m22\nwq'. Der Hauptvorteil der Verwendung exwäre die Möglichkeit, einen einzelnen Befehl mit Pipe-Begrenzung anstelle einer Reihe von Befehlen mit Zeilenumbruch zu verwenden. Andernfalls würden Sie schreiben printf '55m22|wq\n' | ex input, wodurch drei Zeichen gespeichert werden printf '55m22\nwq\n' | ed -s input.
Chepner
3

Es ist etwas länger vials in ed:

vi input
55Gdd23GPZZ

55G... gehe zu Zeile 55
dd... lösche eine Zeile
23G... gehe zu Zeile 23
P... füge die gelöschte Zeile vor Zeile 23 ein
ZZ... schreibe Datei und beende

Jim L.
quelle
8
viauch hat den :mBefehl, gleich wie ed, so :55m22ist auch möglich , in vi.
Filbranden
1
Danke, @filbranden!
Jim L.
2
Historisch viwar eine Verfeinerung von ex, die selbst eine Verfeinerung von war ed.
Chepner