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


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


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:


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}'

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 .


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.


Cela supprime chaque nouvelle ligne, pas toutes les autres lignes.
Trenton

2

En bash:

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

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


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.