Dieses Problem ist möglicherweise am einfachsten zu lösen ed, da es sich im Grunde genommen um einen skriptfähigen Texteditor und nicht um einen Stream-Prozessor handelt. Mit edmüssen Sie beispielsweise nicht alle Zeilen der Datei in einem Array speichern, da dies bereits für Sie erledigt wird.
# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... das wird Hjede Zeile alt machen, die !nicht die erste ist, und die erste, die sie pdruckt. In der $letzten Zeile werden xdie Halte- und Musterbereiche geändert, bevor die Halte Zeile ausgeführt wird. dDadurch werden die gespeicherten Zeilen an die letzte Zeile angehängt. Anschließend werden alle Zeilen aus der Ausgabe gelöscht, die !nicht die $letzten sind.
In der $letzten Zeile werden xdie Leerzeichen erneut s///geändert, das erste \newline-Zeichen wird ersetzt - das sich um das in Zeile 2 hinzugefügte Zeichen kümmert - und das Los wird dann automatisch gedruckt.
AUSGABE:
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
ohne Verwendung des Haltepuffers:
cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... nur um Ihr Beispiel in einer tatsächlichen Datei zu speichern ...
sed '1p;$!d;r infile' <infile | sed '3d;$d'
Dass Umleitungen <infilezu den ersten sed‚s stdin, die nur pdie erste Zeile Rints vor dvon Ausgangs alle Zeilen eleting, die !nicht die $letzte. Die letzte Zeile ist autoprinted, aber es ist auch die einzige Linie , auf der der letzte Befehl ausgeführt wird -, die ist rdie gesamte ead heraus infilewieder zu stdout. All das wird über das |Rohr zum zweiten geleitet, seddas dann nur noch dseine dritte und letzte Eingangsleitung von seinem Ausgang entfernen muss, um die Neuanordnung abzuschließen.
cool, +1. Ich erinnere mich nicht, dass Sie jemals awkLösungen veröffentlicht haben. Sind Sie ein großer sedFan oder haben Sie vielleicht geschrieben sed? ;-)
iruvar
@ 1_CR - Ich weiß nicht, wie man es benutzt awk- ich habe es nie versucht. vielleicht eines Tages ...
Sie speichern jede Zeile im aArray und drucken das Array dann in der gewünschten Reihenfolge (1. Zeile, letzte ( NR) und von 2 bis zum vorletzten.
Mit einer Kombination aus Kopf / Schwanz und Sed:
~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Drucken Sie die erste Zeile, die letzte und löschen Sie mit sed die erste und letzte.
Nur mit sed konnte ich diesen Befehl nur finden. Ich bin sicher, es gibt bessere Möglichkeiten:
~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Wenn es die erste Zeile ist, drucken Sie sie aus (Standard).
Legen Sie es in der zweiten Zeile in den Haltepuffer ( H) und löschen Sie es aus dem Musterbereich ( d). Und wenn es die letzte Zeile ist, drucken Sie sie ( p), holen Sie sich den Haltepuffer ( x), löschen Sie die leere Zeile ( s/^\n//) und drucken Sie sie ( p).
awk
Lösungen veröffentlicht haben. Sind Sie ein großersed
Fan oder haben Sie vielleicht geschriebensed
? ;-)awk
- ich habe es nie versucht. vielleicht eines Tages ...Ein naiver Ansatz mit awk:
Sie speichern jede Zeile im
a
Array und drucken das Array dann in der gewünschten Reihenfolge (1. Zeile, letzte (NR
) und von 2 bis zum vorletzten.Mit einer Kombination aus Kopf / Schwanz und Sed:
Drucken Sie die erste Zeile, die letzte und löschen Sie mit sed die erste und letzte.
Nur mit sed konnte ich diesen Befehl nur finden. Ich bin sicher, es gibt bessere Möglichkeiten:
Wenn es die erste Zeile ist, drucken Sie sie aus (Standard).
Legen Sie es in der zweiten Zeile in den Haltepuffer (
H
) und löschen Sie es aus dem Musterbereich (d
). Und wenn es die letzte Zeile ist, drucken Sie sie (p
), holen Sie sich den Haltepuffer (x
), löschen Sie die leere Zeile (s/^\n//
) und drucken Sie sie (p
).quelle
sed
Teil wäre so etwas wiehead -n -1 f | tail -n +2
.-1
Syntax fürhead
dort ist nicht portabel.Mit Perl:
Mit awk:
AUSGABE
quelle