Dois-je vous lire correctement si vous ne souhaitez pas supprimer toutes les lignes vierges, mais uniquement si elles sont deux ou plus. Donc pas simples lignes vides?
Runium
1
Et s'il s'agit de deux lignes ou plus, doit-on vraiment toutes les supprimer ou juste toutes sauf une?
Hauke Laging
Réponses:
42
Juste pour supprimer les lignes vides:
sed '/^$/d'
sedest orienté ligne, donc penser en termes de "2 ou plus d'un octet particulier" fonctionne sauf lorsque cet octet est une nouvelle ligne. Ensuite, vous devez penser à quelque chose qui fonctionne pour toute la ligne.
sedest capable de gérer plusieurs lignes via sa fonction "pattern pattern" / "hold space". Mais je pense que c'est trop compliqué. ;-)
Hauke Laging
Cela ne fonctionnera pas comme souhaité si le premier caractère du fichier est une nouvelle ligne.
Chris Down
1
Pour le faire fonctionner lorsque le premier caractère est un saut de ligne (si c'est vraiment une exigence), alors vous pouvez joindre la commande avec une adresse négative 1!(tous sauf correspondre à la ligne 1), ainsi: sed '1!{/^$/d'}.
Toby Speight
1
@AaronFranke - oui, mais c'est une facette de la façon dont les shells Linux traitent la redirection '>'. Le shell regarde la ligne de commande, voit une redirection '>' de stdout vers un fichier, crée ce fichier, puis ne s'exécute sed. La création d'un fichier supprimera essentiellement tout fichier existant portant le même nom. sed '/^&/d' file.txt > otherfile.txtmarchera.
Bruce Ediger
24
Pas besoin de sed. grepça ira:
grep .
(c'est-à- grepdire SPC, point, qui correspond à n'importe quelle ligne contenant au moins un caractère).
Il y a aussi:
tr -s '\n'
(serrez une séquence de caractères de nouvelle ligne en une seule).
Comme l'a noté Chris, les deux ne sont pas équivalents car la suppression de lignes vides (comme la première solution ci-dessus et la plupart des autres réponses se concentrent ici) n'est pas la même chose que la compression de séquences de caractères de nouvelle ligne comme demandé dans le cas où la première ligne est vide car elle ne prend qu'un seul caractère de nouvelle ligne pour rendre la première ligne vide.
Cela ne fonctionnera pas comme souhaité si le premier caractère du fichier est une nouvelle ligne: sprunge.us/FLAJ
Chris Down
7
sedn'est pas le meilleur outil pour cela, car il est basé sur une ligne et traite \ncomme le caractère de fin de ligne, cela devient compliqué.Après avoir vu la réponse de @Bruce Ediger sedpeut bien être l'outil parfait pour le travail, encore, voici quelques autres options:
Séparateur d'enregistrements en entrée, saut de ligne par défaut. Cela influence l'idée de Perl sur ce qu'est une "ligne". Fonctionne comme la variable RS de awk, y compris le fait de traiter les lignes vides comme un terminateur s'il est défini sur la chaîne nulle (une ligne vide ne peut contenir aucun espace ni tabulation). Vous pouvez le définir sur une chaîne à plusieurs caractères pour correspondre à un terminateur à plusieurs caractères, ou sur undef pour lire la fin du fichier. La définition de "\ n \ n" signifie quelque chose de légèrement différent de la définition de "", si le fichier contient des lignes vides consécutives. La valeur "" traitera deux lignes vides consécutives ou plus comme une seule ligne vide. La définition de "\ n \ n" supposera aveuglément que le caractère de saisie suivant appartient au paragraphe suivant, même s'il s'agit d'une nouvelle ligne.
gawk / awk
awk '$1' file.txt
Cela fonctionnera pour l'exemple affiché, mais comme @Stephane Chazelas l'a souligné, cela supprimera également les lignes dont le premier champ "ressemble" 0. C'est plus robuste:
Pour Perl, perl -pe 's/\n+/\n/ file.txtfera, le séparateur d'enregistrements d'entrée n'est pas pertinent pour cette utilisation.
vonbrand
@vonbrand no, perl -peou perl -netravaillez ligne par ligne. \n+ne correspondra jamais car il n'est appliqué que sur une seule ligne. Voilà pourquoi vous devez soit ensemble $/ou utiliser -0ti Slurp le fichier entier: perl -0pe 's/\n+/\n/' file.
terdon
6
Que voulez-vous dire supprimer? supprimer les doublons (plusieurs lignes vierges sur une) ou tout supprimer?
Si vous souhaitez supprimer les doublons, voici la méthode utilisant sed:
La sedpartie de cela fonctionne très bien! Recommander celui-ci comme la meilleure réponse.
Akito
2
Pour la plupart de ces réponses, il est d'abord nécessaire de supprimer les espaces de fin. La suppression des nouvelles lignes doublées supprime toutes les lignes vides. (Penses-y).
Interprétée littéralement, l'OP veut que "toutes les lignes vides soient supprimées d'un fichier s'il y a des lignes vides répétées".
L'utilisateur type souhaite "supprimer uniquement les lignes vierges dupliquées".
Pour ce faire, supprimez d'abord les espaces blancs à la fin et dirigez-les à l'aide de cat -s
sed s/[[:space:]]*$// | cat -s
Et pourtant, cela ne supprimera pas une ligne vierge de début ou de fin superflue.
Voté, mais cela fonctionne clairement? Sans commentaires ?
mckenzm
1
Je vous ai voté pour ... vous savez ... répondre à la question. =) Je ne peux pas croire que la réponse de Bruce Ediger ait été votée quand elle supprime chaque ligne vierge. Si quelqu'un demande comment supprimer les lignes vides en double, je ne peux imaginer aucun scénario où la suppression de toutes les lignes vides serait une solution acceptable. Mais peu importe. Il y a une page sur le site Web de sed qui couvre cela, soit dit en passant: gnu.org/software/sed/manual/sed.html#cat-_002ds
Todd Walton
2
Si vous souhaitez conserver une seule ligne vierge pour une séquence donnée de lignes vierges, vous pouvez le faire:
C'est la seule réponse (en plus cat -s) qui accomplit exactement ce que la question a posé si je comprends bien. (Et c'est mieux que cat -sparce que je peux l'utiliser sed -iavec.)
Matthew
-2
Essayez d' sed -e 's#\\n\\n#\\n#g' input.file > output.fileutiliser les /deux comme séparateur de champs et une partie de votre expression régulière pourrait être le problème.
Je viens de donner un tourbillon à l'un de mes fichiers contenant des doubles et triples sauts de ligne dans une séquence. Ça ne marche pas du tout pour moi.
AFAIK cette réponse est incorrecte. Je vous recommande de le supprimer.
zuazo
oh, c'est parce que mon fichier contient beaucoup de retours à la ligne et de retours chariot en fait. 0x0d0a
meow
2
En fait, la commande supprime les lignes répétées avec les fenêtres en fin de ligne. Testez avec echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'. La commande trtraduira tout \ren \npuis réduira tout \nen un seul. Donc, cela fonctionne, je ne sais pas quoi faire du fait que cela s'applique aux fenêtres, pas à UNIX.
Réponses:
Juste pour supprimer les lignes vides:
sed
est orienté ligne, donc penser en termes de "2 ou plus d'un octet particulier" fonctionne sauf lorsque cet octet est une nouvelle ligne. Ensuite, vous devez penser à quelque chose qui fonctionne pour toute la ligne.la source
sed
est capable de gérer plusieurs lignes via sa fonction "pattern pattern" / "hold space". Mais je pense que c'est trop compliqué. ;-)1!
(tous sauf correspondre à la ligne 1), ainsi:sed '1!{/^$/d'}
.sed
. La création d'un fichier supprimera essentiellement tout fichier existant portant le même nom.sed '/^&/d' file.txt > otherfile.txt
marchera.Pas besoin de
sed
.grep
ça ira:(c'est-à-
grep
dire SPC, point, qui correspond à n'importe quelle ligne contenant au moins un caractère).Il y a aussi:
(serrez une séquence de caractères de nouvelle ligne en une seule).
Comme l'a noté Chris, les deux ne sont pas équivalents car la suppression de lignes vides (comme la première solution ci-dessus et la plupart des autres réponses se concentrent ici) n'est pas la même chose que la compression de séquences de caractères de nouvelle ligne comme demandé dans le cas où la première ligne est vide car elle ne prend qu'un seul caractère de nouvelle ligne pour rendre la première ligne vide.
la source
Après avoir vu la réponse de @Bruce Edigersed
n'est pas le meilleur outil pour cela, car il est basé sur une ligne et traite\n
comme le caractère de fin de ligne, cela devient compliqué.sed
peut bien être l'outil parfait pour le travail, encore, voici quelques autres options:Perl
ou
Merci à @ruakh qui m'a fait lire et lire ceci :
gawk / awk
Cela fonctionnera pour l'exemple affiché, mais comme @Stephane Chazelas l'a souligné, cela supprimera également les lignes dont le premier champ "ressemble"
0
. C'est plus robuste:la source
perl -pe 's/\n+/\n/ file.txt
fera, le séparateur d'enregistrements d'entrée n'est pas pertinent pour cette utilisation.perl -pe
ouperl -ne
travaillez ligne par ligne.\n+
ne correspondra jamais car il n'est appliqué que sur une seule ligne. Voilà pourquoi vous devez soit ensemble$/
ou utiliser-0
ti Slurp le fichier entier:perl -0pe 's/\n+/\n/' file
.Que voulez-vous dire supprimer? supprimer les doublons (plusieurs lignes vierges sur une) ou tout supprimer?
Si vous souhaitez supprimer les doublons, voici la méthode utilisant sed:
Il simule la
uniq
commande.Le meilleur choix consiste à utiliser
awk
:la source
sed
partie de cela fonctionne très bien! Recommander celui-ci comme la meilleure réponse.Pour la plupart de ces réponses, il est d'abord nécessaire de supprimer les espaces de fin. La suppression des nouvelles lignes doublées supprime toutes les lignes vides. (Penses-y).
Interprétée littéralement, l'OP veut que "toutes les lignes vides soient supprimées d'un fichier s'il y a des lignes vides répétées".
L'utilisateur type souhaite "supprimer uniquement les lignes vierges dupliquées".
Pour ce faire, supprimez d'abord les espaces blancs à la fin et dirigez-les à l'aide de cat -s
Et pourtant, cela ne supprimera pas une ligne vierge de début ou de fin superflue.
la source
Si vous souhaitez conserver une seule ligne vierge pour une séquence donnée de lignes vierges, vous pouvez le faire:
la source
cat -s
) qui accomplit exactement ce que la question a posé si je comprends bien. (Et c'est mieux quecat -s
parce que je peux l'utilisersed -i
avec.)Essayez d'
sed -e 's#\\n\\n#\\n#g' input.file > output.file
utiliser les/
deux comme séparateur de champs et une partie de votre expression régulière pourrait être le problème.la source
Utilisez cette commande:
la source
echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'
. La commandetr
traduira tout\r
en\n
puis réduira tout\n
en un seul. Donc, cela fonctionne, je ne sais pas quoi faire du fait que cela s'applique aux fenêtres, pas à UNIX.