Comment supprimer des lignes vides / vides d'un fichier sous Unix (espaces compris)?

61

Comment puis-je supprimer les lignes vides / vides (y compris les espaces uniquement) d'un fichier sous Unix / Linux à l'aide de la ligne de commande?

contenu de fichier.txt

Line:Text
1:<blank>
2:AAA
3:<blank>
4:BBB
5:<blank>
6:<space><space><space>CCC
7:<space><space>
8:DDD

sortie souhaitée

1:AAA
2:BBB
3:<space><space><space>CCC
4:DDD
Michael Ellick Ang
la source
1
C'est une réponse épique qui donne pratiquement toutes les solutions possibles en utilisant grep, sed, awk: stackoverflow.com/questions/16414410/…
wisbucky

Réponses:

87

Cette ligne sed devrait faire l'affaire:

sed -i '/^$/d' file.txt

Le -isignifie qu'il va modifier le fichier en place.

Martijn Heemels
la source
13
Il faut en fait "/ ^ * $ / d" pour supprimer les lignes ne contenant que des espaces.
Sean Reifschneider
2
@SeanReifschneider Cette exigence n'était pas dans la question lorsque cette réponse a été écrite?
Kasperd
4
@SeanReifschneider "/ ^ \ s * $ / d" ne serait-il pas meilleur car il inclurait des tabulations? Bien que ce ne soit pas mentionné dans le post original, cela me semble une option plus forte.
mrswadge
Je suisbad flag in substitute command: 'e'
ishandutta2007
31

grep

La solution simple consiste à utiliser la commande grep( GNU ou BSD ) comme ci-dessous.

  • Supprimer les lignes vierges (non compris les lignes avec des espaces).

    grep . file.txt
    
  • Supprimer complètement les lignes vides (y compris les lignes avec des espaces).

    grep "\S" file.txt
    

Remarque: Si vous obtenez des couleurs indésirables, cela signifie que vous grepalias grep --color=auto(contrôle type grep). Dans ce cas, vous pouvez ajouter un --color=noneparamètre ou simplement exécuter la commande en tant que \grep(qui ignore l'alias).


ripgrep

Similaire avec ripgrep(convient pour des fichiers beaucoup plus volumineux).

Supprimer les lignes vierges sans les lignes avec des espaces:

rg -N . file.txt

ou comprenant des lignes avec des espaces:

rg -N "\S" file.txt

Voir également:

Kenorb
la source
2
grep .semble être la solution la plus simple.
Leo
L'inconvénient de la grep .comparaison avec les autres solutions est qu'il met en évidence tout le texte en rouge. Les autres solutions peuvent préserver les couleurs d'origine. Comparez unbuffer apt search foo | grep .àunbuffer apt search foo | grep -v ^$
wisbucky
1
@ wisbucky Vous voyez les couleurs, car elles grepsont associées à un alias grep --color=autosur votre système (vérifiez par :) type grep. Vous pouvez l'exécuter en tant que \grepou utiliser un --color=noneparamètre.
Kenorb
@kenorb Si vous utilisez grep --color=none ., vous obtiendrez tout le texte blanc, qui remplace la couleur mise en forme de la commande d' origine (exemple: apt search foo)
wisbucky
grep .correspondra aux lignes contenant uniquement des espaces, ce que l'OP dit n'est pas désiré.
Jim L.
27
sed '/^$/d' file.txt

d est la commande sed pour supprimer une ligne. ^$est une expression régulière correspondant uniquement à une ligne vide, un début de ligne suivi d'une fin de ligne.

Kamil Kisiel
la source
+1 pour l'explication
Alex Raj Kaliamoorthy
Cette commande ne produit pas la même sortie que celle demandée par OP (elle produit 5 lignes et non 4).
Kenorb
22

Vous pouvez utiliser l'option -v avec grep pour supprimer les lignes vides correspondantes.

Comme ça

grep -Ev "^$" file.txt
Jdabney
la source
4
Je ne crois pas que vous ayez besoin de -E, du moins pas avec GNU grep, mais à part ça, je suis ravi de voir que cela est fait avec grep! C'est ce que je recherche de préférence à sed, à chaque fois; les filtres en ligne me semblent meilleurs que les éditeurs en ligne.
MadHatter
Si vous souhaitez ignorer les lignes vides et commentées, en particulier lorsque vous utilisez des fichiers de configuration, utilisezgrep -Ev '^#|^$' file.txt
Govind Kailas
7

Voici une awksolution:

awk NF file.txt

Avec Awk, NFdéfinissez uniquement sur des lignes non vierges. Lorsque cette condition est remplie, l’action par défaut d’Awk consiste à imprimer la ligne entière.

Steven Penny
la source
6

Pour supprimer les lignes vides, vous pouvez utiliser de nouvelles répétitions de lignes avec tr:

cat file.txt | tr -s '\n' '\n'
Siddhadev
la source
Cela produit 6 lignes et non 4 comme OP a demandé.
Kenorb
1

xargs si vous ne craignez pas de décaper les espaces

$ docker run -it --rm alpine sh
/ # cat <<eof > /tmp/file
> one
>
>   two
> three
>
>
>   four
> eof
/ # cat /tmp/file
one

  two
three


  four
/ # cat /tmp/file | xargs -n1
one
two
three
four
Christian Calloway
la source
0

Ex / Vim

Voici la méthode utilisant exeditor (une partie de Vim):

ex -s +'v/\S/d' -cwq test.txt

Pour plusieurs fichiers (éditer sur place):

ex -s +'bufdo!v/\S/d' -cxa *.txt

Remarque: la :bufdocommande n'est pas POSIX .

Sans modifier le fichier (simplement imprimer sur la sortie standard):

cat test.txt | ex -s +'v/\S/d' +%p +q! /dev/stdin
Kenorb
la source
0

Pour moi, la commande @ martigin-heemels lançait une erreur, ce qui a corrigé le problème (c.-à-d. Un paramètre factice sur i),

sed -i '' '/^$/d' file.txt

ishandutta2007
la source
0

Le moyen le plus simple de supprimer les lignes vides (sans espaces) consiste à utiliser cat -s:

$ cat -s file
$ some-command | cat -s

Du moins si vous ne souhaitez pas éditer un fichier sur place mais écrivez par exemple sur le terminal. En outre, cela n'implique aucune activité amusante liée aux regex, il est donc très facile de s'en souvenir, même pour les personnes qui ne sont pas favorables à RE.


De man cat:

-s, --squeeze-blank never more than one single blank line

Peut-être différent sur différents systèmes d'exploitation mais était présent sur quelques Linux et OpenBSD lors de ma dernière vérification.

kyrill
la source