É mais fácil de fazer com perl :
perl -0777 -pi -e 's{/\*.*?\*/}{/* new comment */}s' file.c
Substituiria a primeira ocorrência de /*...*/ pelo novo comentário.
sed processa o texto uma linha por vez, portanto você não pode corresponder a um texto com várias linhas, a menos que adicione as outras linhas ao espaço do padrão (ou use -z com versões recentes do GUN sed ):
sed -zi 's|/\*.*\*/|/* new comment */|' file.c
Ou portável (assumindo arquivos curtos):
sed -e :1 -e '$!{N;b1' -e '}' -e 's|/\*.*\*/|/* new comment */|' file.c
No entanto, observe que, como sed não suporta o operador *? non-greedy de perl , isso significa que ele corresponderá da primeira ocorrência de /* ao último ocorrência de */ , então substituiria /* comment 1 */ some C code /* comment 2 */ por /* new comment */ .
Fazê-lo com sed é possível, mas mais doloroso. Veja aqui para um exemplo (que também cuida de evitar /* ocorrências dentro de "strings" e algumas outras advertências).
Uma solução simplificada que seria equivalente a perl one seria algo como:
sed '
# load the whole file into the pattern space
:1
$!{
N;b1
}
s/_/_u/g;s/>/_c/g; # use _ as an escape character to escape
# the > we will be using in place of */
s|\*/|>|g; # replace */ with >
s|/\*[^>]*>|/* new comment */|
s|>|*/|g; # undo the replacement and escaping
s/>/_c/g;s/_u/_/g' file.c
Com o GNU awk , você poderia fazer:
awk -v RS='\*/' '
!found && sub(/\/\*.*/, "/* new comment ") {found = 1}
{printf "%s", $0 RT}' file.c