J'ai un dossier avec des commentaires:
foo
bar
stuff
#Do not show this...
morestuff
evenmorestuff#Or this
Je veux juste imprimer tout le code non commenté:
foo
bar
stuff
morestuff
evenmorestuff
Pouvoir retirer des commentaires d'un fichier est si important ... Quelle est la bonne façon de le faire?
Une façon de supprimer tous les commentaires consiste à utiliser grep
avec -o
option:
grep -o '^[^#]*' file
où
-o
: imprime uniquement les correspondances partie de la ligne^
: début de la ligne[^#]*
: tout caractère sauf #
répété zéro ou plusieurs foisNotez que les lignes vides seront également supprimées, mais les lignes avec uniquement des espaces resteront.
Je crois que sed
peut faire un bien meilleur travail que grep
. Quelque chose comme ça:
sed '/^[[:blank:]]*#/d;s/#.*//' your_file
Explication
sed
regardera par défaut votre fichier ligne par ligne et imprimera chaque ligne après avoir éventuellement appliqué les transformations dans les guillemets. (sed '' your_file
affichera simplement toutes les lignes inchangées).sed
deux commandes à exécuter sur chaque ligne (elles sont séparées par un point-virgule)./^[[:blank:]]*#/d
. En anglais, cela signifie que si la ligne correspond à un hachage à son début (précédé d'un nombre quelconque de blancs de début), supprimez cette ligne (elle ne sera pas imprimée).s/#.*//
. En anglais c'est-à-dire, remplacez par une marque de hachage suivie par autant de choses que vous pouvez trouver (jusqu'à la fin de la ligne, c'est-à-dire) avec rien (rien n'est l'espace vide entre les deux derniers //
).Comme d'autres l'ont souligné, sed et d'autres outils basés sur du texte ne fonctionneront pas bien si des parties d'un script ressemblent à des commentaires mais ne le sont pas. Par exemple, vous pourriez trouver un # à l'intérieur d'une chaîne ou le $#
et ${#param}
.
J'ai écrit un formateur Shell appelé shfmt , qui a une fonctionnalité pour réduire le code. Cela comprend la suppression des commentaires, entre autres:
$ cat foo.sh
echo $# # inline comment
# lone comment
echo '# this is not a comment'
[mvdan@carbon:12] [0] [/home/mvdan]
$ shfmt -mn foo.sh
echo $#
echo '# this is not a comment'
L'analyseur et l'imprimante sont des packages Go, donc si vous souhaitez une solution personnalisée, il devrait être assez facile d'écrire un programme Go de 20 lignes pour supprimer les commentaires exactement comme vous le souhaitez.
Vous pouvez obtenir la sortie requise à l'aide de la commande sed. La commande ci-dessous avait fait l'affaire pour moi.
sed 's/#.*$//g' FileName
Où
#.*$
- Regexp filtrera toute la chaîne commençant par #
jusqu'à la fin de la ligneIci, nous devons supprimer ces lignes afin que nous les remplacions par des pièces vides afin de sauter le remplacement.
g
- mentionnant la recherche répétée du modèle jusqu'à la fin du fichier.Syntaxe générale de sed: s/regexp/replacement/flags FileName
Cela a fonctionné pour moi
sed -i.old -E "/^(#.*)$/d" file
Suite à la 2ème réponse de Joseph R., j'ajoute /^$/d
pour supprimer la ligne vierge.
sed '/^[[:blank:]]*#/d;s/#.*//;/^$/d'
cat example.sh
#!/bin/bash
# example script
echo "# test";# echo "# test"
# check the first parameter
if [ "$1" = "#" ]; then
# test couple of different cases
echo "#"; # output # character
echo '\#'; # output # character '#' for test purpose
echo \#\#\#; # comment # comment # comment '# comment'
echo \#
echo \#;
echo \#; # comment
fi
# end of the script
sed -e '1{/^#!/ {p}}; /^[\t\ ]*#/d;/\.*#.*/ {/[\x22\x27].*#.*[\x22\x27]/ !{:regular_loop s/\(.*\)*[^\]#.*/\1/;t regular_loop}; /[\x22\x27].*#.*[\x22\x27]/ {:special_loop s/\([\x22\x27].*#.*[^\x22\x27]\)#.*/\1/;t special_loop}; /\\#/ {:second_special_loop s/\(.*\\#.*[^\]\)#.*/\1/;t second_special_loop}}' example.sh
cat example.sh
#!/bin/bash
echo "# test";
if [ "$1" = "#" ]; then
echo "#";
echo '\#';
echo \#\#\#;
echo \#
echo \#;
echo \#;
fi
Lisez comment cela fonctionne à la source: https://blog.sleeplessbeastie.eu/2012/11/07/how-to-remove-comments-from-a-Shell-script/
J'aime la réponse de Joseph mais j'en avais besoin pour me déshabiller // commentaires aussi donc je l'ai légèrement modifiée et testée sur redhat
# no comments alias
alias nocom="sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' | strings"
# example
cat SomeFile | nocom | less
Je parie qu'il y a une meilleure façon de supprimer les lignes vides que d'utiliser des chaînes, mais c'était la solution rapide et sale que j'ai utilisée.
-à votre santé
La meilleure solution serait d'utiliser la commande:
sed -i.$(date +%F) '/^#/d;/^$/d' ntp.conf
Le -i est la modification sur place mais le préfixe suivant directement indique à sed de créer une sauvegarde. Dans ce cas avec une extension de date (ntp.conf.date) Nous exécutons deux commandes chacune avec un espace d'adressage, la première supprime les lignes commentées et la seconde, séparée de la première par un point-virgule, supprime les lignes vides.
J'ai trouvé cette solution sur: theurbanpenguin.com
Vous pouvez utiliser une correspondance inversée comme ceci:
#grep -v "#" filename
-v, --invert-match Inverse le sens de la correspondance, pour sélectionner les lignes non correspondantes. (-v est spécifié par POSIX.)
cat YOUR_FILE | cut -d'#' -f1
Il utilise #
comme séparateur de colonnes et ne conserve que la première colonne (c'est tout avant #
).
Je poste ce qui fonctionne pour moi et semble avoir le plus de sens, après avoir lu les autres, avec explication. Quelques articles sont venus près, mais je ne pouvais pas encore commenter (parce que je suis un nouveau):
grep -E -v "(^#.*|^$)" filename
-E
= Interpréter le modèle suivant comme une expression régulière, similaire à l'utilisation d'egrep-v
= Imprime l'inversion du motif (les lignes qui ne correspondent pas à l'expression seront imprimées)"(^#.*|^$)"
= ceci a un tube qui désigne une instruction OR. Cette expression indique d'imprimer toute ligne commençant par un #
(et toute autre chose après) ) OR toute ligne avec zéro caractère entre le début et la fin de la ligne.Le -v
Imprimera à l'écran l'inversion de celui-ci, qui sera n'importe quelle ligne avec des caractères qui ne commence pas par un #
.
Aucune des autres réponses ne semble rendre cette justice, soit elles laissent des lignes vides, soit des lignes où le commentaire n'est pas au premier caractère. J'ai fini par utiliser ceci:
cat << EOF >> ~/.bashrc
alias nocom='sed -e "/^\s*#/d" -e "/^\s*$/d"'
EOF
Cela crée un alias, afin que vous n'ayez pas à le mémoriser (ce qui est impossible au départ). Ouvrez une nouvelle session et vous aurez la nouvelle commande nocom
. Ensuite, vous pouvez simplement
nocom /etc/foobar.conf
À votre santé.
Utilisez une expression comme
egrep -v "#|$^" <file-name>
: -v: fera une correspondance inversée
: #: correspondra à toutes les lignes commençant par #
: $ ^: correspondra à toutes les lignes vides