web-dev-qa-db-fra.com

sed + remove "#" et les lignes vides avec une commande sed

comment supprimer des lignes de commentaires (comme # bal bla) et des lignes vides (lignes sans caractères) d'un fichier avec une commande sed?

THX Lidia

22
lidia

Si vous êtes préoccupé par le démarrage de deux processus sed dans un pipeline au lieu d'un, vous ne devriez probablement pas l'être, ce n'est pas que inefficace.

Cependant, si vous do souhaitez un seul processus, vous pouvez utiliser plusieurs arguments -e, comme par exemple:

sed -e 's/#.*$//' -e '/^$/d' inputFile

En réponse à votre commentaire sur pourquoi vous souhaitez un processus unique, souhaitant utiliser sed -i pour la modification sur place, vous pouvez toujours le faire selon la transcription suivante:

pax> echo 'Line # with a comment' >qq
pax> echo >>qq
pax> echo '# Line with only a comment' >>qq
pax> cat qq
Line # with a comment

# Line with only a comment
pax> sed -i -e 's/#.*$//' -e '/^$/d' qq
pax> cat qq
Line
pax> _

Notez comment le fichier est modifié sur place même avec deux options -e. Vous pouvez voir que les deux commandes sont exécutées sur chaque ligne. La ligne avec un commentaire commence par supprimer le commentaire, puis tout est supprimé car il est vide.

En outre, la ligne vide d'origine est également supprimée.

31
paxdiablo

@paxdiablo a une bonne réponse mais elle peut être améliorée.

(1) La clause '/^$/d' ne correspond qu'à 100% de lignes vierges.

Si vous souhaitez également faire correspondre des lignes entièrement blanches (espaces, tabulations, etc.), utilisez plutôt ceci:

'/^\s*$/d'

(2) La clause 's/#.*$//' ne fait correspondre que les lignes commençant par le caractère # dans la colonne 0.

Si vous souhaitez également faire correspondre les lignes ne contenant que des espaces avant le premier #, utilisez plutôt ceci:

'/^\s*#.*$/d'

Les critères ci-dessus peuvent ne pas être universels (par exemple, dans un bloc HEREDOC ou dans une chaîne multiligne Python, les différentes approches peuvent être significatives), mais dans de nombreux cas, la définition conventionnelle des lignes "vides" inclut uniquement les espaces, et "comment "les lignes incluent les espaces, puis -#.

(3) Enfin, sous OSX au moins, la solution @paxdiablo dans laquelle la première clause transforme les lignes de commentaire en lignes vierges et la seconde clause supprime les lignes vides (y compris les commentaires à l'origine) ne fonctionne pas. Il semble plus facile de faire en sorte que les deux clauses /d suppriment les actions comme je l’ai fait.

La commande révisée intégrant ce qui précède est:

sed -e '/^\s*#.*$/d' -e '/^\s*$/d' inputFile
13
Chris Johnson

Ce petit bijou supprime tous les commentaires # , peu importe où ils commencent dans une ligne:

sed -e 's/\s*#.*$//'

Exemple:

text="
this is a # test
#this is a test
#this is a #test
this is # another #test
"

$echo "$text" | sed -e 's/\s*#.*$//'

this is a


this is

Ensuite, cela supprime les lignes vides résultantes:

$echo "$text" | sed -e 's/\s*#.*$//' | sed -e '/^\s*$/d'
5
Elliptical view

Variante alternative utilisant grep:


cat file.txt | grep -Ev '(#.*$)|(^$)'
3
demetrios

vous pouvez utiliser awk

awk 'NF{gsub(/^[ \t]*#/,"");print}' file
1
ghostdog74

Le premier exemple (paxdiablo) est très bon sauf que son fichier ne change pas, il affiche juste le résultat. Si vous voulez le changer en ligne:

Sudo sed -i's /#.*$//;/^$/d 'inputFile 

0
Tim Bikbaev

Sur l'une de mes boîtes Linux, sed comprend les expressions rationnelles étendues avec l'option -r, donc:

sed -r '/ (^\s * #) | (^\s * $)/d' squid.conf.installed 

est très utile pour afficher toutes les lignes non vierges et non commentées. La regex correspond au début de la ligne suivi de zéro ou plusieurs espaces ou tabulations suivis du hachage ou de la fin de la ligne et supprime les lignes correspondantes l'entrée.

0
Graham Nicholls