开发者

Regular Expression to strip comments from Bash script

This is deceptively complex. I need a regular expression to strip comments from Bash shell scripts.

Bear in mind that $#, ${#foo}, string="this # string", string='that # string', ${foo#bar}, ${foo##baar}, and

string="real开发者_StackOverflow中文版ly complex args=$# ${applejack##"jack"} $(echo "$#, again")"; `echo this is a ${#nasty[*]} example`

are all valid shell expressions that should not be stripped.

Edit: Note that:

# This is a comment in bash
  # But so is this
echo "foo bar" # This is also a comment

Edit: Note that lines that might be misconstrued as comments may be tucked inside HEREDOCs but since it is multi-line I can live without handling/accounting for it:

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


You cannot do that with regular expressions.

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

You need to match nested braces. Regular expressions can't do that, unless you're willing to consider PCREs "regular expressions", in which case it would be simpler to just write the parser in Perl.


Just for fun ...

I don't believe you can do this without using/implementing a parser but it's fun seeing how far you can get without doing that.

The closest I gotten is to use a simple regex with sed. It preserves the hash bang which is a definite must but can't cope with the HEREDOC. You could go further but then it might not be fun anymore.

Sample bash script (called doit)

#!/bin/bash
#This
#  is a 
echo $1 #comment

Running that ...

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


echo $1

But obviously there are blank lines produced which you don't want AND it doesn't handle HERE docs.

Again, not a serious suggestion but please play around with it.


EDITED: I admit it! sed won't work for the reasons given in comments - sed doesn't handle lookaheads/lookbehinds. Thanks for pointing that out!

I thought a comment in bash was a line that started with a #. If so, here's your regex:

^#

And here's the sed command that will strip them:

sed -i '' -e 's/^\s*#(?!!).*$//' myfile.sh

EDITED to factor in downvoter's comments: ie

  • allow whitespace before the # using \s*
  • exclude lines that have a ! following the # using negative lookahead (?!!)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜