web-dev-qa-db-fra.com

bash / sed / awk / etc supprimer tous les autres sauts de ligne

une commande bash génère ceci:

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

Je voudrais le diriger vers quelque chose pour qu'il ressemble à ceci:

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
[...]

c'est-à-dire supprimer tous les autres sauts de ligne

J'ai essayé ... |tr "\nGroup" " " mais il a supprimé toutes les nouvelles lignes et a également mangé d'autres lettres. Merci

44
carillonator

ne peut pas tester en ce moment, mais

... | paste - - 

devrait le faire

87
glenn jackman

Une possibilité est:

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

Si le numéro de ligne est divisible par 2, terminez par une nouvelle ligne, sinon, terminez par un espace.

(Testé sur: CentOS 6, GNU Awk 3.1.7)

Utilisation de sed (voir explication ):

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

Lectures complémentaires:

11
cyberx86

Si vous souhaitez utiliser sed, il n'y a aucune raison de lire tout le fichier en mémoire. Vous pouvez fusionner toutes les autres lignes comme ceci:

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

Utilisez n'importe quel caractère que vous souhaitez au lieu de l'espace.

Voici une autre façon d'utiliser awk:

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

Le if/else gère le cas où il y a un nombre impair de lignes dans le fichier. Sans cela, la dernière ligne impaire est imprimée deux fois. Sinon, à titre de comparaison, vous pourriez faire:

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

La façon la plus idiomatique de le faire dans awk est la suivante:

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

Il génère:

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

Pour l'expliquer, nous devons définir chacune des variables intégrées:

  • RS séparateur d'enregistrement. Par défaut à \n (nouvelle ligne).
  • ORS séparateur d'enregistrement de sortie. Par défaut à \n (nouvelle ligne).
  • FS séparateur de champs. Par défaut à (espace).
  • NR numéro d'enregistrement.

Comme le séparateur d'enregistrements par défaut est la nouvelle ligne, un enregistrement est, par défaut, une ligne.

NR%2 est le module de NR/2, pour que ce soit 0 ou 1. 0 pour les lignes paires et 1 pour les lignes impaires.

var=condition?condition_if_true:condition_if_false est l'opérateur ternaire.

Tous ensemble, en disant ORS=NR%2?FS:RS nous définissons le séparateur d'enregistrement de sortie:

  • si le numéro d'enregistrement est sur le formulaire 2k + 1, c'est-à-dire sur des lignes paires, les séparateurs d'enregistrements de sortie sont définis sur FS, c'est-à-dire un espace.
  • si le numéro d'enregistrement est sur le formulaire 2k, c'est-à-dire sur les lignes impaires, les séparateurs d'enregistrements de sortie sont définis sur RS, c'est-à-dire une nouvelle ligne.

De cette façon, les lignes impaires se terminent par un espace, qui est ensuite joint à la ligne suivante. Après cette ligne, une nouvelle ligne est imprimée.

Plus d'informations dans Awk idiomatique .

3
fedorqui

Cela fonctionne pour moi sur Linux:

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

Cela remplace un espace vide pour un caractère de nouvelle ligne; vous devez échapper au caractère de nouvelle ligne pour que les choses fonctionnent correctement.

3
Bret McMillan

En bash:

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

Si Perl est une option:

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

s/\n/ / remplace la nouvelle ligne par un espace
$. est le numéro de ligne

1
Chris Koknat