8
votes

Expression régulière pour dépasser les commentaires du script Bash

Ceci est trompeusement complexe. J'ai besoin d'une expression régulière pour dépasser les commentaires des scripts de Bash Shell.

Gardez à l'esprit que $ # code>, $ {# fio} code>, String = "Code # chaîne " code>, string =" tandis # chaîne ' code>, $ {foo # bar} code>, $ {foo # / code >, et p> xxx pré>

sont toutes des expressions de shell valides qui doivent pas em> être dépouillées. P>

EDIT: fort> Notez que: p> xxx pré>

EDIT: strong> Notez que les lignes qui pourraient être mal interprétées comme des commentaires peuvent être nichés à l'intérieur des hicheocs, mais comme il est multi-lignes, je peux vivre sans manipuler / compter pour cela: p>

cat<<EOF>>out.txt
This is just a heredoc
# This line looks like a comment, but it isn't
EOF


6 commentaires

Je commence à sentir que cela pourrait ne pas être possible avec une simple regex, surtout maintenant que vous avez ajouté la mise en garde Heredoc. Vous devrez peut-être faire une analyse de la syntaxe à la place


D'accord avec Carl, ne pensez pas que c'est régulier. Il y a trop de cas de bord pour les scripts arbitraires.


Il apparaît que sur une ligne donnée, seul le # le plus droit doit être testé pour voir s'il fait partie d'une "chaîne" ou de $ # ou $ {# # {# $ expansion]}.


@Jeffg - ne tombe-t-elle pas quand dans un heedoc?


@Chris McCauley, oui. Je dois concéder que l'affaire Heredoc doit être lancée du problème, à cause de sa nature multiligne.


Vous pouvez également mettre des commentaires dans Subshells: (# Ceci est un commentaire )


3 Réponses :


3
votes

édité: je l'avoue! SED ne fonctionnera pas pour les raisons données dans les commentaires - SED ne gère pas les lunettes de vue / regarder les regards. Merci d'avoir souligné cela!

Je pensais qu'un commentaire à Bash était une ligne qui a commencé avec un #. Si tel est le cas, voici votre regex: xxx

et voici la commande sed qui les dépassera: xxx

édité au facteur Dans les commentaires de Downvoter: IE

  • Autoriser les espaces avant le # en utilisant \ s *
  • Exclure les lignes qui ont un ! suivant le # à l'aide de la lunette négative (? !!)

4 commentaires

Les commentaires peuvent également avoir à la fois des caractères blancheurs et non-blancs entre le ^ (début de la ligne) et le #, de sorte que cette regex manque de commentaires en retrait, par exemple, ou des commentaires clos à la fin d'une ligne.


Qui supprimerait également le document initial #! / Bin / bash (ou équivalent) ... pas bon


La lookahead négatif peut-elle également protéger le $ # variable et $ {# araylength [*]} et $ {Suppression de la sous-chaîne} Cases? Aussi y a-t-il un moyen de gérer le "HASH # à l'intérieur des chaînes" cas?


@Bohemian - Je pensais que SED manquait de lookahead négatif?



7
votes

Vous ne pouvez pas faire cela avec des expressions régulières.

echo ${baz/${foo/${foo/#bar/foo}/bar}/qux}


0 commentaires

4
votes

juste pour le plaisir ...

Je ne crois pas que vous puissiez faire cela sans utiliser / mettre en œuvre un analyseur, mais c'est amusant voir jusqu'où vous pouvez obtenir sans cela. P>

Le plus proche I Gotten est d'utiliser une simple regex forte> avec sed forte>. Il préserve le hachage qui est un déficit défini mais ne peut pas faire face à l'Heredoc. Vous pourriez aller plus loin, mais ce n'est peut-être plus amusant. P>

échantillon Script Bash (appelé DOIT) P>

cat doit | sed -e 's/#[^!].*$//'
#!/bin/bash


echo $1


3 commentaires

Merci pour la suggestion; Les lignes vides ne sont pas un problème, mais cela traiterait probablement tous les personnages après le dollar-signer dans la ligne suivante en tant que commentaire, une bande: echo "Il y a $ # arguments"


@Jeffg a accepté. Vous devriez être de plus en plus intelligent avec la regex et même à cela, cela ne soutiendrait pas les Heredocs. Vraiment vous avez besoin d'un analyseur. Merci pour la question cependant et +1 pour la divertissement me distrayant de certains trucs de travail ennuyeux.


Cela n'attachera pas une ligne avec seulement un hash sur elle, car votre regex nécessite au moins 1 caractères après le hachage.