como usar o SED para substituir comentários em uma seção de comentários

2

Suponha que eu tenha um arquivo que comece com o seguinte

    /*********************************************************
    blah blah blah
    blah blah blah
    blah blah blah
    *********************************************************/
    Actual code follows here
    code 
    code 
    code

O comando que usei:

    sed -i 's/(/*).*(*/)/ newcomment /1' file

mas recebi a mensagem de erro

    sed: -e expression #1, char 14: unknown option to 's'

p.s. minha pergunta é ... como eu posso substituir os comentários "bla bla bla bla ..." com outros bloah bloah bloah comentários?

    
por Chan 18.08.2016 / 10:56

2 respostas

2

É 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
    
por 18.08.2016 / 11:13
1

Escape os parênteses e barras

 sed -i 's/\(\/*\).*\(*\/\)/ newcomment /1' file
    
por 18.08.2016 / 10:59