bash / sed / awk / etc supprime chaque nouvelle ligne

39

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 pousser à quelque chose pour le faire ressembler à 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 chaque nouvelle ligne

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

carillonateur
la source
2
trest entièrement basé sur les caractères: vous avez demandé à tr de supprimer les nouvelles lignes et tous les 'G', 'r', 'o', 'u' et 'p'.
Glenn Jackman

Réponses:

80

Je ne peux pas tester maintenant, mais

... | paste - - 

devrait le faire

Glenn Jackman
la source
5
+1 - fonctionne et est élégant. (Il met un onglet entre les lignes - paste -d ' ' - -ajoutera un espace à la place si nécessaire)
cyberx86
4
Pourriez-vous s'il vous plaît expliquer comment fonctionne la commande? Pourquoi y a-t-il deux -? Merci
bbaja42
7
pasteest utilisé pour concaténer les lignes correspondantes de fichiers: paste file1 file2 file3 .... Si l'un des arguments "fichier" est "-", les lignes sont lues à partir de l'entrée standard. S'il y a 2 "-" arguments, alors coller prend 2 lignes de stdin. Etc. Voir la page de manuel .
Glenn Jackman
10

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:

cyberx86
la source
8

Si vous voulez utiliser sed, il n'y a aucune raison de lire le fichier entier en mémoire. Vous pouvez fusionner chaque ligne comme ceci:

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

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

Voici un autre moyen d'utiliser awk:

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

Le if/elsegè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}'
En pause jusqu'à nouvel ordre.
la source
1
Un commentaire tardif: 1) utilisez toujours un spécificateur de format pour printf au cas où la chaîne aurait des signes de pourcentage, 2) pour éviter la dernière ligne dupliquée, définissez $ 0 sur "" -awk '{printf "%s", $0; $0=""; getline; print " " $0}'
glenn jackman
3

La manière la plus idiomatique de le faire awkest la suivante:

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

Il produit:

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:

  • RSséparateur d'enregistrement. La valeur par défaut est \n(nouvelle ligne).
  • ORSséparateur d'enregistrement de sortie. La valeur par défaut est \n(nouvelle ligne).
  • FSséparateur de champ. La valeur par défaut est (espace).
  • NR numéro d'enregistrement.

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

NR%2est le module de NR/2, de sorte qu'il soit 0ou 1. 0pour les lignes paires et 1pour les lignes impaires.

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

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

  • si le nombre d'enregistrements est sur le formulaire 2k + 1, c'est-à-dire sur des lignes paires, les séparateurs d'enregistrement en 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'enregistrement en 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'infos dans awk idiomatique .

Fedorqui
la source
2

Cela fonctionne pour moi sur Linux:

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

Ceci 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.

Bret McMillan
la source
Cela supprime chaque nouvelle ligne, pas toutes les autres lignes.
Trenton
2

En bash:

... | while read l1; do read l2; echo "$l1 $l2"; done
jfg956
la source
1

Si Perl est une option:

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

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

Chris Koknat
la source
-1

Que diriez-vous d'utiliser grep?

.. | grep -v '^Group State'
pkhamre
la source
Cela élimine les lignes alternatives. Le PO veut les ajouter.
pause jusqu'à nouvel ordre.
Oui, après avoir relu la question, je viens de me rendre compte que :)
pkhamre