53 votes

Bash/sed/awk/etc supprime chaque autre saut de ligne

Une commande bash affiche ceci :

Nom d'exécution: vmhba2:C0:T3:L14
État du groupe: actif
Nom d'exécution: vmhba3:C0:T0:L14
État du groupe: actif non optimisé
Nom d'exécution: vmhba2:C0:T1:L14
État du groupe: actif non optimisé
Nom d'exécution: vmhba3:C0:T3:L14
État du groupe: actif
Nom d'exécution: vmhba2:C0:T2:L14
État du groupe: actif

J'aimerais le rediriger vers quelque chose pour que cela ressemble à ceci :

Nom d'exécution: vmhba2:C0:T1:L14 État du groupe: actif 
Nom d'exécution: vmhba3:C0:T3:L14 État du groupe: actif non optimisé
Nom d'exécution: vmhba2:C0:T2:L14 État du groupe: actif
[...]

c'est-à-dire supprimer chaque autre saut de ligne

J'ai essayé ... |tr "\nGroup" " " mais cela a supprimé tous les sauts de ligne et a également supprimé d'autres lettres. Merci

3 votes

tr est entièrement basé sur des caractères : vous avez demandé à tr de supprimer les sauts de ligne et tous les 'G', 'r', 'o', 'u' et 'p'.

0 votes

Cherchez-vous toutes les autres (simples) nouvelles lignes à la fin d'une ligne, ou plusieurs nouvelles lignes comme \n\n, ou les deux ?

103voto

marshally Points 2260

Je ne peux pas tester pour le moment, mais

... | colle - - 

devrait le faire

8 votes

+1 - fonctionne et est élégant. (Il met une tabulation entre les lignes - paste -d ' ' - - ajoutera un espace si nécessaire)

6 votes

Pouvez-vous s'il vous plaît expliquer comment fonctionne la commande ? Pourquoi y a-t-il deux - ? Merci

12 votes

Coller est utilisé pour concaténer les lignes correspondantes des fichiers : coller fichier1 fichier2 fichier3 .... Si l'un des arguments "fichier" est "-", alors les lignes sont lues à partir de l'entrée standard. S'il y a 2 arguments "-", alors coller prend 2 lignes de stdin. Et ainsi de suite. Voir la page de manuel.

11voto

cyberx86 Points 20450

Une possibilité est :

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

Si le numéro de ligne est divisible uniformément par 2, se termine par une nouvelle ligne, sinon, se termine par un espace.

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

En utilisant sed (voir explication) :

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

Lecture supplémentaire :

0 votes

Le deuxième lien vers linux.dsplabs.com.au est cassé

8voto

jason saldo Points 5036

Si vous voulez utiliser sed, il n'y a pas de raison de lire tout le fichier en mémoire. Vous pouvez fusionner chaque autre ligne de cette manière :

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

Utilisez n'importe quel caractère à la place de l'espace.

Voici une autre méthode en utilisant 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 serait imprimée deux fois. Sinon, pour comparaison, vous pourriez faire :

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

1 votes

Un commentaire tardif : 1) utilisez toujours un spécificateur de format pour printf au cas où la chaîne contiendrait 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}'

4voto

zacaj Points 171

La manière la plus idiomatique de le faire en awk est la suivante :

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

Cela donne en sortie :

Nom d'exécution : vmhba2:C0:T3:L14 État du groupe : actif
Nom d'exécution : vmhba3:C0:T0:L14 État du groupe : actif non optimisé
Nom d'exécution : vmhba2:C0:T1:L14 État du groupe : actif non optimisé
Nom d'exécution : vmhba3:C0:T3:L14 État du groupe : actif
Nom d'exécution : vmhba2:C0:T2:L14 État du groupe : actif

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

  • RS séparateur d'enregistrements. Par défaut \n (nouvelle ligne).
  • ORS séparateur de sortie d'enregistrements. Par défaut \n (nouvelle ligne).
  • FS séparateur de champs. Par défaut un espace.
  • NR nombre d'enregistrements.

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

NR%2 est le modulo de NR/2, donc cela sera 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.

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

  • si le nombre d'enregistrements est de la forme 2k + 1, c'est-à-dire sur des lignes paires, alors le séparateur de sortie d'enregistrements est défini comme FS, c'est-à-dire un espace.
  • si le nombre d'enregistrements est de la forme 2k, c'est-à-dire sur des lignes impaires, alors le séparateur de sortie d'enregistrements est défini comme RS, c'est-à-dire une nouvelle ligne.

De cette manière, 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.

0 votes

Cela repose également astucieusement sur le fait que l'expression donne également soit FS ou RS, qui sont (évidemment) tous les deux véridiques. Si l'expression renvoyait quelque chose de faux (par exemple (ORS=...)&&0), rien ne serait imprimé.

3voto

Bret McMillan Points 101

Cela fonctionne pour moi sur Linux :

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

Cela remplace un espace vide par un caractère de saut de ligne ; vous devez échapper le caractère de saut de ligne pour que tout fonctionne correctement.

1 votes

Cela supprime chaque saut de ligne, pas chaque autre saut de ligne.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X