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?

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.


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/

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

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.


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

-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

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