0

I have a bash script that I am trying to write to remove the $ Header $ pattern with a blank line

lines like below need to be replaced with blank line

 /* $Header$ */
 /*$Header$*/
 /* $Header$ This is a test*/

My script is as below but I get unexpected EOF while looking for matching. How can this be fixed?

#!/bin/bash
for f in *.java;
do
 echo "Processing $f file ..." ;
 sed -i "s/\$Header\$//g' $f
done

Execution 2

Based on the comments I modified the scripts as below and executed the below but it only replaced $Header$, it still left the /* */ . Is there a way I can replace the whole line with a blank line if a pattern matches in the line?

#!/bin/bash
for f in *.java;
do
 echo "Processing $f file ..." ;
 sed -i 's/\$Header\$//g' "$f"
done
serah
  • 2,057
  • 7
  • 36
  • 56

1 Answers1

0

Your attempt has a number of problems.

  • The unbalanced quotes are a syntax error.
  • Your regex only targets the $Header$ string, not the full line.
  • There is probably no need to run this in an explicit loop.

Try this:

sed -i 's%^[ \t]*/\*\([^*]*\|\*[^/]\)*\$Header\$\([^*]*\|\*[^/]\)*\*/[ \t]*$%%' *.java

If your sed doesn't recognize \t as a tab, replace \t with a literal tab (if you are trying this at the prompt, ctrl-v tab will insert a literal tab in many shells).1

This regex is pretty complex. It looks for

  • ^ - beginning of line
  • [ \t]* - any amount of leading whitespace
  • /\* - literal start of comment
  • \([^*]*\|\*[^/]\)* - anything which isn't a comment close sequence (so either anything which isn't *, or a literal * followed by something which isn't /, repeated zero or more times)
  • \$Header\$ - the literal string $Header$, where the dollar signs have to be escaped for the regex
  • ... again, that sequence which is not a comment terminator
  • \*/ - followed by the comment terminator
  • [ \t]* - with any amount of trailing whitespace before
  • $ - end of line

On MacOS and other *BSD-based platforms, you need sed -i '' with an empty non-optional parameter to the -i option. If platform portability is important, switching to Perl might be the easiest route forward (curiously) and will allow for some simplification of the regex.

It's not uncommon to have the CVS $Header$ keyword in a string instead of in a comment, but I am assuming that's out of scope for this question. (It's probably not impossible to find an existing question about that if you actually need to extend this.) Maybe you also want to capture expressions like $Header: moo bar baz$ though? Updating the regex to do this should not be hard.


1 To find out if your sed supports \t, try this:

printf '*\t*\n' | sed 's/\t/yes/'

If you see *yes* you are good.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    This started out as comments to @RavinderSingh's answer, but I guess became significant enough to warrant a separate answer. – tripleee Jan 22 '19 at 13:44
  • Thank you or posting a separate answer I have deleted mine now(may be I didn't get complete requirement of OP). – RavinderSingh13 Jan 22 '19 at 13:56