bash / sed / awk / etc entferne alle anderen Zeilenumbrüche


39

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 an etwas weiterleiten, 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
[...]

dh alle anderen Zeilenumbrüche entfernen

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


2
trist vollständig zeichenbasiert: Sie haben tr gebeten, Zeilenumbrüche und alle Zeichen 'G', 'r', 'o', 'u' und 'p' zu entfernen.
Glenn Jackman

Antworten:


80

kann momentan nicht testen, aber

... | paste - - 

Sollte es tun


5
+1 - funktioniert und ist elegant. (Es wird ein Tabulator zwischen den Zeilen paste -d ' ' - -
eingefügt. Bei

4
Könnten Sie bitte erklären, wie der Befehl funktioniert? Warum gibt es zwei -? Danke
bbaja42

7
pasteentsprechende Zeilen von Dateien verketten verwendet wird : paste file1 file2 file3 .... Wenn eines der "file" -Argumente "-" ist, werden Zeilen aus der Standardeingabe gelesen. Wenn es 2 "-" Argumente gibt, nimmt das Einfügen 2 Zeilen von stdin. Und so weiter. Siehe die Manpage .
Glenn Jackman

10

Eine Möglichkeit ist:

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

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

(Getestet unter: CentOS 6, GNU Awk 3.1.7)

Verwendung von sed (siehe Erklärung ):

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

Weitere Lektüre:


8

Wenn Sie verwenden möchten sed, gibt es keinen Grund, die gesamte Datei in den Speicher zu lesen. Sie können jede andere Zeile wie folgt zusammenführen:

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

Verwenden Sie anstelle des Leerzeichens ein beliebiges Zeichen.

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

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

Das if/elsebehandelt den Fall, in dem sich eine ungerade Anzahl von Zeilen in der Datei befindet. Ohne wird die ungerade letzte Zeile zweimal gedruckt. Andernfalls könnten Sie zum Vergleich Folgendes tun:

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

1
Ein spätes Kommentar: 1) immer einen Formatbezeichner für printf verwenden , falls die Zeichenfolge hat Zeichen Prozent, 2) die duplizierten letzte Zeile gesetzt $ 0 auf „“ zu vermeiden -awk '{printf "%s", $0; $0=""; getline; print " " $0}'
glenn Jackman

3

Der idiomatischste Weg, dies zu tun, awkist 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:

  • RSDatensatztrennzeichen. Standardmäßig \n(neue Zeile).
  • ORSAusgabesatztrennzeichen. Standardmäßig \n(neue Zeile).
  • FSFeldtrennzeichen. Standardmäßig (Leerzeichen).
  • NR Nummer des Datensatzes.

Da das Standard-Datensatztrennzeichen die neue Zeile ist, ist ein Datensatz standardmäßig eine Zeile.

NR%2ist der Modul von NR/2, so dass es entweder 0oder sein wird 1. 0für gerade und 1für ungerade Zeilen.

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

Alles ORS=NR%2?FS:RSin allem definieren wir das Trennzeichen für die Ausgabedatensätze:

  • Wenn sich die Anzahl der Datensätze im Formular 2k + 1befindet, dh in geraden Zeilen, werden die Trennzeichen für die Ausgabedatensätze auf FSein Leerzeichen gesetzt.
  • Wenn sich die Anzahl der Datensätze im Formular 2kbefindet, dh in ungeraden Zeilen, werden die Trennzeichen für die Ausgabedatensätze auf RSeine neue Zeile gesetzt.

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 .


2

Das funktioniert bei mir unter Linux:

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

Dies ersetzt ein Leerzeichen für ein Zeilenumbruchzeichen. Sie müssen das Zeilenumbruch-Zeichen umgehen, damit die Dinge richtig funktionieren.


Dadurch werden alle Zeilenumbrüche entfernt, nicht alle anderen Zeilenumbrüche.
Trenton

2

In der Bash:

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

1

Wenn Perl eine Option ist:

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

s/\n/ /Ersetzt Newline durch Leerzeichen,
$.ist dies die Zeilennummer


-1

Wie wäre es mit grep?

.. | grep -v '^Group State'

Dadurch entfallen die alternativen Zeilen. Das OP möchte, dass sie angehängt werden.
Bis auf weiteres angehalten.

Ja, nachdem ich die Frage noch einmal gelesen hatte, wurde mir gerade klar, dass :)
pkhamre
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.