Ich versuche, die Reihenfolge der Linien in einem bestimmten Muster zu ändern. Arbeiten mit einer Datei mit vielen Zeilen (z. B. 99 Zeilen). Für alle drei Zeilen möchte ich, dass die zweite Zeile die dritte Zeile und die dritte die zweite Zeile ist.
BEISPIEL.
1- Eingabe:
gi_1234
My cat is blue.
I have a cat.
gi_5678
My dog is orange.
I also have a dog.
...
2- Ausgabe:
gi_1234
I have a cat.
My cat is blue.
gi_5678
I also have a dog.
My dog is orange.
...
linux
text-processing
command-line
Annick Raymond
quelle
quelle
NR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.Das heißt,
p
drucken Sie die aktuelle Zeile, holen Sie sich dien
ext- Zeile, machen Sieh
sie alt, holen Sie sich dien
ext-G
Zeile und halten Sie die gehaltene Zeile (hängen Sie sie an den Musterraum an) undp
drucken Sie diesen zweizeiligen Musterraum, wobei die dritte und zweite Zeile vertauscht sind.quelle
Ein weiterer awk- Ansatz:
Die Ausgabe:
(getline L2)>0 && (getline L3)>0
- extrahiert die nächsten 2 Datensätze, falls vorhandenjeweils 2. und 3. Datensätze zugewiesen
L2
undL3
Variablen bzw.quelle
line2
, etc.Verwenden
perl
und ein kurzes Skript:Das Skript verarbeitet die gesamte Datei. Für jede Zeile (gespeichert in
$_
) erhält es die nächsten beiden Zeilen ($l2
und$l3
) und druckt sie in der gewünschten Reihenfolge: Zeile1, Zeile3, Zeile2.quelle
Ein Weg könnte wie folgt sein:
Alternative,
Ergebnisse
quelle
Warum nicht einfach eine while-Schleife machen? In erweiterter Form:
Im "einzeiligen Format":
Ausgänge:
quelle
Perl
Die Idee hier ist, dass wir den Modulo-Operator
%
mit der Zeilennummernvariablen verwenden$.
, um herauszufinden, welche jede erste, welche jede Sekunde und welche jede dritte Zeile ist. Für jede 3. Zeile ist der Rest 0, während für jede 1. und 2. Zeile entsprechende Nummern vorhanden sind.Prüfung:
Kleinere Verbesserung
Der Ansatz mit dem Speichern der zweiten Zeile in einer Variablen weist einen Fehler auf. Was ist, wenn die letzte Zeile die "zweite" ist, dh für diese Zeile ist der Rest 2? Der Originalcode in meiner und DopeGhotis Antwort wird nicht gedruckt,
My dog is orange
wenn wir die letzte Zeile weglassen . In beiden Fällen besteht die Lösung darin, einenEND{}
Codeblock zu verwenden und die temporäre Variable nach dem Drucken zu deaktivieren. Mit anderen Worten:und
Auf diese Weise funktioniert der Code für eine beliebige Anzahl von Zeilen in einer Datei, nicht nur für die durch 3 teilbaren.
Zusätzlicher Fix für das in den Kommentaren erwähnte Problem
In awks Fall, wenn die letzte Zeile in der Datei eine Ausgabe von 1 für $ ergibt. % 3, der vorherige Code hat das Problem der Ausgabe einer leeren neuen Zeile aufgrund des bedingungslosen Druckens von
END{print delay}
, daprint
die in den Kommentaren erwähnte Funktion immer eine neue Zeile an die Variable anfügt, mit der er arbeitet. Im Falle einerperl
Version tritt dieses Problem nicht auf, da mit der Funktion-ne
flagsprint
die Newline nicht angehängt wird.Nichtsdestotrotz besteht die Lösung in awks Fall darin, bedingt zu machen, wie von Dope Ghoti in den Kommentaren erwähnt, die Länge der temporären Variablen zu überprüfen. Die Perl-Version des gleichen Fixes wäre:
quelle
awk
) behobenNR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.-ne
Flags keine neue Zeile ausgibt. Es wird zwar gedruckt, aber es ist eine Nullzeichenfolge, keine nachgestellte Zeilenumbruch. Trotzdem habe ich die Erwähnung des Problems und den gleichen Fix in meine Antwort aufgenommen. Vielen Dank !Vim
Nicht für lange Dateien geeignet, aber dennoch praktisch, wenn Sie nur eine Datei bearbeiten und beispielsweise einige Yaml-Strophen neu anordnen möchten.
Nehmen Sie zuerst ein Makro auf:
Und dann die gewünschte Anzahl wiederholen:
Oder einfach nur zB
Erläuterung:
quelle
@q @q @q
, ist dies auf diese Weise möglich3@q
- dreimal wiederholen.100@q
- Wiederholen Sie das Makro 100 Mal.Verwendung:
./shuffle_lines.awk input.txt
Überprüfen Sie shebang
#!/usr/bin/awk -f
, da derawk
Standort auf Ihrem System unterschiedlich sein kann.quelle