2010-07-17 26 views
2

J'apprends à utiliser sed et une exigence hypothétique:Comment remplacer plusieurs lignes vides intermédiaires avec seulement 1 ligne vide chaque

bash$ cat states 
California 


Massachusetts 


Arizona 

Wisconsin 

je voudrais la sortie: (En fait, je ne veux qu'une seule ligne vide entre)

California 

Massachusetts 

Arizona 

Wisconsin 

S'il vous plaît suggérer des façons de le faire avec sed. Faut-il utiliser concept d'espace modèle multiligne etc.

Merci,

Jagrati


En réponse à l'un des commentaires, Ok, j'ai couru quelques scripts de test, et je me suis trompé avec hypopthèse que les critères de sélection d'espace d'adresse est appliquée une seule fois. Il semble être activé encore et encore.

bash$ cat file 
a 
b 
c 
a 
b 
c 

bash$ sed -e '/a/,/b/s/$/x/g' file 
ax 
bx 
c 
ax 
bx 
c 

J'avais l'impression qu'il produirait:

ax 
bx 
c 
a 
b 
c 

Alors Quelqu'un pourrait-il s'il vous plaît expliquer comment le produit sed en cas séparés par des virgules des espaces d'adressage.

+0

Sed traite le fichier dans une boucle. Les adresses Regex ne sont pas des positions absolues dans un fichier. Chaque ligne est évaluée pour voir si elle se situe dans une plage d'adresses regex.Une fois la fin d'une plage atteinte, le test du début de la plage regex reprend. –

Répondre

6

Essayez cela, il supprimera toutes les lignes vides consécutives

cat states | sed '/./,/^$/!d' 

sorties:

California 

Massachusetts 

Arizona 

Wisconsin 
+1

utilisation inutile de chat. – ghostdog74

+0

Cela fonctionne, mais ne comprend pas très bien comment ... cela utilise des adresses séparées par des virgules. 2ème adresse signifie une ligne vide. La première adresse signifie n'importe quel caractère. puis il supprime les lignes ne correspondant pas à ce critère. Mais la sélection de l'espace adresse n'est-elle pas appliquée une seule fois. Bon, comment est-il capable de se débarrasser de 2 lignes vides entre le Massachusetts et l'Arizona? Pouvez-vous m'expliquer comment cela fonctionne? – xyz

+0

Ok, j'ai exécuté quelques scripts de test, et je me suis trompé avec l'hypopthèse. une fois que. Il semble être activé encore et encore. bash fichier $ cat a b c a b c bash $ sed -e '/ a /,/b/s/$/x/g' fichier hache bx c hache bx c j'avais l'impression qu'il produirait: hache bx c a b c – xyz

1

vous pouvez utiliser awk ainsi

$ cat file 
California 


Massachusetts 


Arizona 

Wisconsin 

$ awk 'NF{print;print ""}' file 
California 

Massachusetts 

Arizona 

Wisconsin 
2

Je sais que l'OP explicitement demandé un solution en utilisant sed et/ou awk, mais le problème pourrait également être résolu avec juste cat:

cat -s file 

Sinon, voici une autre façon de résoudre le problème avec sed:

sed '/./!d; G' file 

qui exploite G pour ajouter une ligne vide à toutes les lignes non vides trouvés dans des fichiers.

+0

juste une petite note que cette insertion ligne vide après la dernière ligne aussi bien, mais bien sûr que cela peut être pris en charge, par sed -e '/./!d' -e '$! s/$/\ > /' états Alors votre base idée de le faire en 2 passes fonctionne essentiellement. – xyz

2

Ceci peut être accompli sans sed, mais aussi sans répondre à vos besoins d'apprentissage sed:

cat -s states 

Il est intéressant de noter que les trois exemples pour ce faire donné info sed pour GNU sed sont chacun beaucoup plus complexe que dalton's et marco's réponses.

Voici les versions condensées en une seule ligne:

sed ':x;/^\n*$/{N;bx};s/\n*/\n/' states 

sed '1,/^./{/./!d};:x;/./!{N;s/^\n$//;tx}' states 

sed -ne '/./!d;:x;p;n;/./bx;:z;n;/./!bz;i\ ' -e 'bx' states 
+0

Seul le dernier de ces 3 exemples fonctionne. Le 1er insère des lignes vides supplémentaires avant la première ligne, et le 2ème ne laisse aucune ligne vide entre la Californie et le Massachusetts. – xyz

+0

+1 pour une réponse correcte que * seulement * utilise 'cat' - Je ne pense pas avoir déjà vu ça :) –

+0

@learnerforever: J'aurais dû inclure les informations du fichier' info' qui mentionne et des lignes vides à la fin. La ligne vide manquante est un bug dans leur script! Changer le '1' en un' 0' (GNU 'sed' seulement) semble résoudre ce problème. Le premier semble être amélioré en ajoutant '1!' Juste avant le 's'. –

0
grep . file > file_op 
+0

Je ne pense pas qu'il remplace deux lignes vides avec un. – ppaulojr