0

I would like to remove all the text between the strings /* and */ in a file, where the strings may occur on different lines and surround a comment. For example I would like to remove the following seven lines which are contained between /* and */:

/* "CyIHTAlgorithm.pyx":81
 * @cython.wraparound(False)
 * @cython.cdivision(True)
 * cdef inline object IHTReconstruction2D(fType_t[:,:] data,             # <<<<<<<<<<<<<<
 *                         fType_t[:,:] residualFID,
 *                         fType_t[:,:] CS_spectrum,
 */

I have managed to do this using sed where the strings occur on the same line: sed -i.bak 's/\(\/\*\).*\(\*\/\)/\1\2/' test.txt but I'm not sure how to extend this to multiple lines in the same file:

I have also tried: sed -i.bak '/\/\*/{:a;N;/\*\//!ba;s/.*\/\*\|\*\/.*//g}' test.txt following the ideas here (Extract text between two strings on different lines)

This deletes the /* at the beginning and */ but not the intervening text.

Community
  • 1
  • 1
218
  • 1,754
  • 7
  • 27
  • 38
  • see if your version of sed has the `-z` option, which would allow NUL to be line separator instead of newline... – Sundeep Mar 02 '17 at 15:30
  • related http://stackoverflow.com/questions/13061785/remove-multi-line-comments – Bertrand Martel Mar 02 '17 at 15:34
  • It's not too hard if you know that there never is non-comment code on the same line as your comment starts or ends, but for the general case, it's more of a pain. – Benjamin W. Mar 02 '17 at 15:54

5 Answers5

2

Why not to work with sed ranges?

$ cat tmp/file13
first line
/* "CyIHTAlgorithm.pyx":81
 * @cython.wraparound(False)
 * @cython.cdivision(True)
 * cdef inline object IHTReconstruction2D(fType_t[:,:] data,             # <<<<<<<<<<<<<<
 *                         fType_t[:,:] residualFID,
 *                         fType_t[:,:] CS_spectrum,
 */
before last line
last line

$ sed '/\/\*/,/\*\//d' tmp/file13
first line
before last line
last line
George Vasiliou
  • 6,130
  • 2
  • 20
  • 27
0

you can use sed or cut but they are really designed for a pattern so each line should match it. you should declare first line and last line by getting the lumber line of the start and finish and then you can wrap it into a function.

so, 1) get the line number for /* part 2) get the last line number for */ 3) you can use "while read line;" loop and cut every line in between using cut or sed.

0

awk is really better suited for this kind of things. It supports ranges out of the box with the /pattern/,/pattern2/ syntax.

awk '/[:space:]*\/\*/,/[:space:]*\*\// {next} {print}' file.txt

It works the following way: for the lines between the two patterns it executes {next} actually skipping the line, for everything else it just prints the input.

mshrbkv
  • 309
  • 1
  • 5
  • This gives me a syntax error. Could you also explain how the syntax works here? – 218 Mar 02 '17 at 16:12
  • There was actually an error with the `else` statement in the initial command. Now it should be fine. – mshrbkv Mar 02 '17 at 16:13
0

The following will try to do more, so test first if it fits your needs.

cpp -P test.txt
Walter A
  • 19,067
  • 2
  • 23
  • 43
0

I found the answer here: https://askubuntu.com/questions/916424/how-to-replace-text-between-two-patterns-on-different-lines

sed -n '1h; 1!H; ${ g; s/<head>.*<\/head>/IF H = 2 THEN\n  INSERT FILE 'head.bes'\nEND/p }' myProgram.bes

Notes: This replaces all lines between <head> ... </head> (inclusive) in an HTML document with:

IF H = 1 THEN
  INSERT FILE 'head.bes'
END
Mr. de Silva
  • 382
  • 2
  • 11