Strang84
Strang84

Reputation: 43

How to insert comment block with sed

I am programming in bash to modify a large collection of files built in C and I need to comment out segments of information (/* */).

The line reads: *action.acroread: {APPMGR_acroread("blah.pdf");}

I want to insert a comment string "/* */" before the {APPMGR... and close it at the end of the line.

Currently I have the code

    for i_file in $file_list[@]}; do
        sed -i '/^*action.acroread/ s|.*|/* & */|' $i_file
        ...

    done

Which inserts a /* at the beginning of the line and a */ at the end of the line, commenting out the whole line. It also prevents multiple commenting blocks from being added in case I run the script multiple times.

What I need to do is to add /* in front of {APPMGR_acroread(“blah.pdf”);} and */ at the end of the line, so the end result should look like

*action.acroread: /* {APPMGR_acroread(“blah.pdf”);} */ 

What I have so far is

sed -i ‘/^action.acroread/ s|.{APPMGR_acroread|/* & */|’ $i_file 

This results in the following output

*action.acroread:/*  {APPMGR_acroread */(“blah.pdf”);} 

In addition, running it a second time causes a second pair of comment blocks to appear

*action.acroread:/* /*  {APPMGR_acroread */ */(“blah.pdf”);} 

The blah.pdf is different inside every file. (blah.pdf, blah2.pdf, blah3.pdf, etc)

How can I modify the code to only comment block the second half of the line in addition to preventing multiple comment blocks when running the script multiple times? Thanks.

Upvotes: 2

Views: 315

Answers (2)

potong
potong

Reputation: 58371

This might work for you (GNU sed):

sed -E 's#^(\*action\.acroread: )(...)?(\{.*\})(...)?#\1/* \3 */#' file

If a line begins *action.acroread: there may or may not be 3 characters before an opening { and 3 characters following a closing } either way replace the line with the first and the third back references, with the third back reference surrounded by /* and */.

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626689

The * and . are special in sed POSIX regex patterns. You need to escape them. Also, you need to capture what you need to keep and what you need to wrap with /*...*/ into separate groups.

You can use

sed -i '/^\(\*action\.acroread[^{]*\)\(.*\)/ s||\1/* \2 */|' "$i_file"

See the online sed demo:

s='line...
*action.acroread: {APPMGR_acroread("blah.pdf");}
another line...'
sed '/^\(\*action\.acroread[^{]*\)\(.*\)/ s||\1/* \2 */|' <<< "$s"
## => 
#    line...
#    *action.acroread: /* {APPMGR_acroread("blah.pdf");} */
#    another line...

Details

  • /^\(\*action\.acroread[^{]*\)\(.*\)/ - finds lines that start with *action.acroread, and captures into Group 1 the prefix (*action.acroread) and then any zero or more chars other than {, and then captures the rest of the line into Group 2
  • s||\1/* \2 */| - replaces the found match with Group 1, /* , Group 2, and */.

Upvotes: 1

Related Questions