Home > other >  Using gawk or sed to inplace change line after or before every other match
Using gawk or sed to inplace change line after or before every other match

Time:02-04

I am trying to change the comment format for many files. Currently I have

//-----------------------------------------------------------
//   NAME : Class
//   DESCRIPTION : Vague information
//-----------------------------------------------------------

The number of - may be different with each file, or even with each case. I would like something like this to keep readability with the rest of the code while still allowing compatibility with a documenting program:

//-----------------------------------------------------------
/*!
//   NAME : Class
//   DESCRIPTION : Vague information
*/
//-----------------------------------------------------------

But this is also acceptable, and for sure easier:

/*!
//   NAME : Class
//   DESCRIPTION : Vague information
*/

For a start, I have tried something like

$ gawk -i inplace '/^\/\/--.*/&&v %2 {sub(/^\/\/--.*, "\/\*!")}' filename.cpp and then $ gawk -i inplace '/^\/\/--.*/{sub(/^\/\/--.*, "\*\/")}' filename.cpp

which obviously has some syntax errors; the goal was to change every odd instance of //---* with /*!, and then replacing //---* with */, and for just one file, instead of many .cpp and .h/.hpp files.

CodePudding user response:

Given:

$ cat file
//-----------------------------------------------------------
//   NAME : Class
//   DESCRIPTION : Vague information
//-----------------------------------------------------------

With THIS regex, you can use perl:

$ perl -0777 -pE 's/^(\/\/- \R)(\/\/[\s\S]*?)(^\/\/- \R?)/\1\/\*!\n\2\*\/\n\3/gm' file 
//-----------------------------------------------------------
/*!
//   NAME : Class
//   DESCRIPTION : Vague information
*/
//-----------------------------------------------------------

Perl also has an inplace option.

CodePudding user response:

Using sed

$ sed -E 'N;s~-\n~&/*!\n~;s~\n/ -~\n*/&~' input_file
//-----------------------------------------------------------
/*!
//   NAME : Class
//   DESCRIPTION : Vague information
*/
//-----------------------------------------------------------

CodePudding user response:

perl -0777 -wnE'
    say s{ //- \n\K (//.*?) (//- \n) }{/*!\n$1*/\n$2}sgrx
' file_with_comment_blocks.txt

Broken into lines only for readability. Modifiers (at the end of regex) are:

  • s with it the . matches a newline as well

  • g repeat throughout the whole string ("global")

  • r so to return the new string (or the unchanged original). Used here for printing

  • x ignore spaces, so use them for readability (also allows newlines and #-comments)

This only prints so it can be redirected to a file for a result while it is safe for testing.

Or, change so to rewrite the file in-place

perl -0777 -i.bak -wnE'
    s{ //- \n\K (//.*?) (//- \n) }{/*!\n$1*/\n$2}sgx
' file_with_comment_blocks.txt

If backup isn't wanted then use -i (no .bak). See Command-line switches in perlrun

  • Related