it-swarm.com.de

bash / sed / awk / etc entferne jede andere neue Zeile

ein Bash-Befehl gibt Folgendes aus:

Runtime Name: vmhba2:C0:T3:L14
Group State: active
Runtime Name: vmhba3:C0:T0:L14
Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14
Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14
Group State: active
Runtime Name: vmhba2:C0:T2:L14
Group State: active

Ich möchte es auf etwas leiten, damit es so aussieht:

Runtime Name: vmhba2:C0:T1:L14 Group State: active 
Runtime Name: vmhba3:C0:T3:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T2:L14 Group State: active
[...]

d.h. jede andere neue Zeile entfernen

Ich habe es versucht ... |tr "\nGroup" " " aber es wurden alle Zeilenumbrüche entfernt und auch einige andere Buchstaben aufgefressen. Vielen Dank

44
carillonator

kann momentan nicht testen, aber

... | paste - - 

sollte es tun

87
glenn jackman

Eine Möglichkeit ist:

awk 'ORS=NR%2?" ":"\n"'

Wenn die Zeilennummer gleichmäßig durch 2 teilbar ist, beenden Sie mit einer neuen Zeile, andernfalls mit einem Leerzeichen.

(Getestet auf: CentOS 6, GNU Awk 3.1.7)

Verwendung von sed (siehe Erklärung ):

sed ':a;N;$!ba;s/\nGroup/ Group/g'

Weiterführende Literatur:

11
cyberx86

Wenn Sie sed verwenden möchten, gibt es keinen Grund, die gesamte Datei in den Speicher einzulesen. Sie können jede andere Zeile folgendermaßen zusammenführen:

sed 'N;s/\n/ /' inputfile

Verwenden Sie ein beliebiges Zeichen anstelle des Leerzeichens.

Hier ist eine andere Möglichkeit, awk zu verwenden:

awk '{printf "%s", $0; if (getline) print " " $0; else printf "\n"}' inputfile

Das if/else behandelt den Fall, dass die Datei eine ungerade Anzahl von Zeilen enthält. Ohne sie wird die ungerade letzte Zeile zweimal gedruckt. Andernfalls könnten Sie zum Vergleich Folgendes tun:

awk '{printf "%s", $0; getline; print " " $0}'

Der idiomatischste Weg, dies in awk zu tun, ist wie folgt:

awk 'ORS=NR%2?FS:RS' file

Es gibt aus:

Runtime Name: vmhba2:C0:T3:L14 Group State: active
Runtime Name: vmhba3:C0:T0:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14 Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14 Group State: active
Runtime Name: vmhba2:C0:T2:L14 Group State: active

Um dies zu erklären, müssen wir jede der eingebauten Variablen definieren:

  • RS Datensatztrennzeichen. Der Standardwert ist \n (Neue Zeile).
  • ORS Trennzeichen für Ausgabedatensätze. Der Standardwert ist \n (Neue Zeile).
  • FS Feldtrennzeichen. Der Standardwert ist (Leerzeichen).
  • NR Nummer des Datensatzes.

Da das Standardtrennzeichen für Datensätze die neue Zeile ist, ist ein Datensatz standardmäßig eine Zeile.

NR%2 Ist der Modul von NR/2, So dass es entweder 0 Oder 1 Ist. 0 Für gerade Zeilen und 1 Für ungerade Zeilen.

var=condition?condition_if_true:condition_if_false Ist der ternäre Operator.

Alles in allem definieren wir mit ORS=NR%2?FS:RS Das Trennzeichen für den Ausgabedatensatz:

  • wenn sich die Anzahl der Datensätze in der Form 2k + 1 befindet, dh in geraden Zeilen, werden die Trennzeichen für die Ausgabedatensätze auf FS gesetzt, dh auf ein Leerzeichen.
  • wenn die Anzahl der Datensätze in der Form 2k liegt, dh in ungeraden Zeilen, werden die Trennzeichen für die Ausgabedatensätze auf RS gesetzt, dh auf eine neue Zeile.

Auf diese Weise enden ungerade Zeilen mit einem Leerzeichen, das dann mit der nächsten Zeile verbunden wird. Nach dieser Zeile wird eine neue Zeile gedruckt.

Weitere Infos in Idiomatic awk .

3
fedorqui

Das funktioniert bei mir unter Linux:

... | tr "\\n" " "

Dies ersetzt ein leeres Leerzeichen für ein Zeilenumbruchzeichen. Sie müssen dem Zeilenumbruchzeichen entkommen, damit die Dinge richtig funktionieren.

3
Bret McMillan

In Bash:

... | while read l1; do read l2; echo "$l1 $l2"; done
2
jfg956

Wenn Perl eine Option ist:

Perl -pe 's/\n/ / if $. % 2 == 1' file

s/\n/ / ersetzt Zeilenumbruch durch Leerzeichen
$. ist die Zeilennummer

1
Chris Koknat