modificar linhas contendo palavras / caracteres específicos e não contendo outros

0

Estou empenhado em encontrar uma maneira de modificar várias linhas em vários arquivos que contenham palavras / caracteres específicos, mas não outros. Para ser mais específico, gostaria de transformar todas as declarações de variáveis em arquivos fortran de real para real(kind=r8) . Por exemplo, as linhas abaixo:

  • var= (var1*REAL(j)-var2*REAL(j)*var3)
  • REAL :: pwr10
  • INTRINSIC REAL
  • REAL(kind=r16) :: qr(n), qaorg, qx
  • REAL, DIMENSION(-1:nx, -1:ny) :: arg1
  • REAL(kind=r8) :: y3

deve se tornar:

  • var= (var1*REAL(j)-var2*REAL(j)*var3)

  • REAL(kind=r8) :: pwr10

  • INTRINSIC REAL
  • REAL(kind=r16) :: qr(n), qaorg, qx
  • REAL(kind=r8), DIMENSION(-1:nx, -1:ny) :: arg1
  • REAL(kind=r8) :: y3

Eu sei como selecionar as linhas específicas usando o grep, mas não usando o sed para modificá-las. alguém pode ajudar por favor?

    
por S. Carli 11.06.2018 / 11:03

2 respostas

2
$ sed 's/REAL\([^(].*::\)/REAL(kind=r8)/' file
var= (var1*REAL(j)-var2*REAL(j)*var3)
REAL(kind=r8) :: pwr10
INTRINSIC REAL
REAL(kind=r16) :: qr(n), qaorg, qx
REAL(kind=r8), DIMENSION(-1:nx, -1:ny) :: arg1
REAL(kind=r8) :: y3

A expressão sed

s/REAL\([^(].*::\)/REAL(kind=r8)/

substituirá todos os REAL por REAL(kind=r8) , desde que

  1. A string REAL não é seguida imediatamente por ( .
  2. Existe um :: em algum lugar mais tarde na mesma linha.

Do jeito que eu escrevi, a string REAL pode ocorrer em qualquer lugar na linha. Use ^REAL no lugar do primeiro REAL na expressão se a palavra tiver ocorrido primeiro na linha (sem espaços ou qualquer coisa entre o início da linha e a palavra).

    
por 11.06.2018 / 11:12
0
perl  -pe '/\h::\h/ && /^\h*REAL(?!\()\K/ and s//(kind=r8)/' input.txt

para ser lido como:

  • quando cada linha tem uma subcadeia "::" delimitada por espaço em branco.
  • a palavra-chave "REAL" começa no início da linha, opcionalmente precedida por espaço em branco e não vê um colchete de abertura à direita.
  • quando ambas as condições acima forem atendidas, executamos a substituição.
  • o s // (kind = r8) / command significa usar o regex da correspondência anterior com sucesso e substituí-lo por qualquer coisa que esteja no RHS.

Resultado

var= (var1*REAL(j)-var2*REAL(j)*var3)
REAL(kind=r8) :: pwr10
INTRINSIC REAL
REAL(kind=r16) :: qr(n), qaorg, qx
REAL(kind=r8), DIMENSION(-1:nx, -1:ny) :: arg1
REAL(kind=r8) :: y3
    
por 11.06.2018 / 12:46