4

I have a Java project, in which I have JavaDoc comments

/** ... */

other multi-line-comments

/* ... */

line comments

// ...

and my own "explanatory comments"

//* ...

When I release my code, I would like to have all line comments removed - not the other comments though. I though I would do it with sed, but so far I have not been successful. I am trying the following:

#!/bin/bash

while read -d $'\0' findfile ; do
  echo "${findfile}"
  mv "${findfile}" "${findfile}".veryold
  cat "${findfile}".veryold | sed -e 's|//[^\*"]*[^"]*||' -e 's/[ ^I]*$//' | grep -A1 . | grep -v '^--$' > "${findfile}"
  rm -f "${findfile}".veryold
done < <(find "${1}" -type f -print0)

What am doing wrong? Note that // in "..." should not be removed, since they might be part of an URL.

The crucial part is

-e 's|//[^\*"]*[^"]*||'
  • First of all, you should create a collection of testlines, which can be used, to see, if a solution works and might be further extended, if it misses important cases. – user unknown Apr 11 '18 at 11:42
1

At first, your script could be simplified to a one-liner:

find "$1" -type f -name '*.java' -print -exec sed -i -e '...' '{}' \;

Second, this is a problem which is hardly solvable using regular expressions, since their grammar does not support context-sensitivity. That means you cannot know if a // is inside a string literal or not.

Ignoring that fact, you might try it with:

s|//[^*"][^"]*$||

This assumes that you don't use double quotes as part of your comments.

  • I don't see how your regex takes care of left over white space and two consecutive blank lines. Also it seems that your answer is very similar to my try: However you did not escape the asterik inside the first brackets - is that not necessary? – Make42 Sep 24 '15 at 12:37
  • Why not 's|//[^*"]*[^"]*$||' as I wrote? Why did you leave out the second asterisk? – Make42 Sep 24 '15 at 12:43
  • 2
    Inside character classes (the brackets), you don't need to escape meta-characters. This would be illogical and even could be wrong! (remember, a character class always matches exactly one character - so [\*] could mean: accept one of \ and * OR only accept *). Your regex is just a complicated way of the regex //[^"]*$ since the second character class is a superset of the first and both are optional (ie. repeated zero times). – cbley Sep 25 '15 at 7:11
0

I'm not sure sed can do complex matches other multiple lines.

With perl remove all comments :

perl -e '$_=join("",<>);s%/\*.*?\*/%%gs;s%//.*$%%gm;print' SomeFile.java

With perl remove all non-javadoc comments outside of pairs of "" :

perl -e '$_=join("",<>);s%/\*([^*].*?)?\*/%%gs;s%^([^\"\n\r]*(\"[^\"\n\r]*\"[^\"\n\r]*?)*?)//([^*\n\r].*)?$%$1%gm;print' SomeFile.java

Here is a more compact version with search of all *.java files and generation of .bak files :

 find . -name '*.java' -print0 | xargs -r -0 perl -n -p -0 -i.bak -e 's%/\*([^*].*?)?\*/%%gs;s%^([^\"\n\r]*(\"[^\"\n\r]*\"[^\"\n\r]*?)*?)//([^*\n\r].*)?$%$1%gm'

But this will remove // inside /** */

A more complex script would be necessary to avoid that :

You'll have to replace /** */ with __temp_comment_# (replace # with an changing number)

then replace "..." with __temp_quote_#

then remove comment

then change back __temp_quote_# and __temp_comment_# to original text

  • "But this will remove // inside /** /" This is okay. But how do I make sure that //, //**, //*** etc. are not removed, while // ... without a directly following asterisk is removed? – Make42 Sep 24 '15 at 15:04
  • // will be removed, but not //* : this is already included in my second expression. This is made with //([^*\n\r].*)?$ : // follow by nothing or any characters but * and carry return, then anything to the end of line. – Vouze Sep 24 '15 at 15:12
  • How do I include your expression into a (long) bash command? Do I just use what cbley wrote and use your perl instead of his sed command or do I use my script above? – Make42 Sep 24 '15 at 15:14
  • I edited my answer with the search of *.java files. – Vouze Sep 29 '15 at 16:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.