Remplacement de plusieurs lignes vides par une seule ligne vierge dans vim / sed

42

La question dit plus ou moins tout. Je suis conscient que /^$/dcela supprimera toutes les lignes vides, mais je ne vois pas comment dire «remplacer deux lignes vides ou plus par une seule ligne vierge»

Des idées?

Andrew Bolster
la source

Réponses:

48

Si vous ne tirez pas vim ou sed pour une autre utilisation, cat dispose en fait d'un moyen simple et pratique pour réduire plusieurs lignes vierges, utilisez-le cat -s.

Si vous étiez déjà dans vim et je voulais rester là - bas, vous pouvez le faire avec la recherche interne et de le remplacer par l' émission: :%s!\n\n\n\+!^M^M!g(Le ^ M est la représentation visuelle d'une nouvelle ligne, vous pouvez le saisir en appuyant sur Ctrl+ vEnter), ou vous sauver la tapant simplement en les bombardements au chat: :%!cat -s.

Caleb
la source
wow, je ne connaissais pas l' -soption de chat - juste une note historique, ce n'est pas dans POSIX, mais semble être disponible dans BSD et GNU cat.
maxschlepzig
2
Marquer comme «gagnant» pour le :%!cat -s. Apprendre quelque chose GNnew tous les jours!
Andrew Bolster
3
Je pense que vous pouvez aussi utiliser \ r au lieu de ^ M comme ceci:%s!\n\n\n\+!\r\r!g
Niko Bellic
J'avais besoin de ça aujourd'hui. Merci Caleb! :)
Dɑvïd
19

Utilisez \npour indiquer une nouvelle ligne dans le modèle de recherche. Utilisez Ctrl+ Mdans le texte de remplacement ou une référence arrière. Voir :help patternet :help sub-replace-special(lié depuis :help :s).

%s/\(\n\n\)\n\+/\1/
Gilles, arrête de faire le mal
la source
Pouvez-vous s'il vous plaît expliquer comment fonctionne le modèle de recherche?
Sagar Jain
@sjmp Condition: remplacez deux lignes vides ou plus par une seule ligne vierge. Mise en œuvre: remplacez trois nouvelles lignes consécutives ou plus par deux nouvelles lignes. Voir le manuel pour une explication des constructions utilisées dans la commande.
Gilles 'SO- arrête d'être méchant'
Mais pourquoi avez-vous besoin d'utiliser un groupe lorsque son contenu est corrigé?
Sabuncu
@Sabuncu Vous n'avez pas besoin d'utiliser un groupe. Mais pourquoi ne pas utiliser un groupe? Ici, j'ai utilisé un groupe parce que vous ne pouvez pas copier-coller une commande avec une nouvelle ligne dans le texte de remplacement: vous devez insérer un caractère Ctrl + M littéral, \ncela ne fonctionne pas dans le texte de remplacement.
Gilles, arrête d'être méchant
Maintenant, je comprends, merci d’avoir pris le temps de répondre.
Sabuncu
6

Si vous êtes dans Vim, faites simplement ceci:

:%!cat -s
coanor
la source
2
Vous voudrez peut-être ajouter quelques détails sur la façon dont cela fonctionne, même s'il ne s'agit que d'une citation de la manpage.
jasonwryan
N'a pas fonctionné sur Windows 7
user674669
0

Utiliser Perl:

perl -00 -pe ''

-00 L'option de ligne de commande active le mode slurp de paragraphe, ce qui signifie que Perl lit le texte paragraphe par paragraphe plutôt que ligne par ligne.

Majid Azimi
la source
0

Avec sed (GNU sed) 4.2.2:

sed -r '
  /^\s*$/ { 
    # blank line
:NEXT
    N # append next line to pattern space - if none, autoprint PS and exit
    s/^\s*$\n^\s*$//g;t NEXT # if 2 blank lines, clear PS and loop to NEXT
  }
  # else, autoprint PS and next/exit
' < $MYFILE
PJ_Finnegan
la source
-2

Je sais que c'est un code idiot, mais je voulais résoudre ce problème en moins de 10 minutes, et cela a fonctionné

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done
Mahmoud Zalt
la source
1
uniqsupprime les lignes égales adjacentes. Ce qui n'est pas ce que veut OP.
pacholik
@pacholik dit-il clairement "Remplacement de plusieurs lignes vides par une seule ligne vierge" NE PAS enlever les lignes égales adjacentes !!!
Mahmoud Zalt
3
Oui, exactement ...
pacholik