Regular expression to highlight comments from Bash script

This is deceivingly complicated. I need a regular expression to highlight comments from Bash shell scripts.

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

 string="really complex args=$# ${applejack##"jack"} $(echo "$#, again")"; `echo this is a ${#nasty[*]} example` 

- All valid shell expressions that should not be removed.

Edit: Note:

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

Edit: Please note that lines that may be misinterpreted as comments may be refilled inside the HEREDOC, but since this is a multi-line line, I can live without processing / accounting:

 cat<<EOF>>out.txt This is just a heredoc # This line looks like a comment, but it isn't EOF 
+6
source share
3 answers

You cannot do this with regular expressions.

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

You need to match nested braces. Regular expressions cannot do this unless you want to consider PCRE "regular expressions", in which case it would be easier to just write a parser in Perl.

+7
source

Just for fun ...

I do not believe that you can do this without using / implementing the parser, but itโ€™s fun to watch how far you can go without it.

The closest I got is a simple regular expression with sed . It saves a hash hang which is specific but cannot handle HEREDOC. You could go further, but then it may not be fun.

Bash script example (called doit)

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

Launching this ...

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

But obviously there are empty lines that you don't want, and they don't handle HERE.

Again, not a serious offer, but please play with it.

+4
source

EDITED: I admit it! sed will not work for the reasons stated in the comments - sed does not handle lookaheads / lookbehinds. Thanks for pointing this out!

I thought the comment in bash was a line starting with C #. If so, here is your regex:

 ^# 

And here is the sed command that will separate them:

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

EDITED is related to lower level comments: ie

  • resolve space before # with \s*
  • exclude lines having ! following # using negative scan (?!!)
+2
source

Source: https://habr.com/ru/post/892682/


All Articles