Reconhecimento de padrões entre duas sentenças em um arquivo que possui espaços e caracteres especiais?

0

Eu tenho um arquivo no qual quero imprimir todas as linhas entre dois padrões. Pattern1 = # Begin TRACE A Data e Pattern 2 = # Done Data $capture , quero imprimir todas as linhas entre pattern1 e pattern2.

Arquivo 1:

# Lower Limit 
LIMIT_FLAG=0
LIMIT_POINT0=2884982910000.000000 -102800 -1
LIMIT_POINT1=2892982910000.000000 -102800 -1

# Limit Done

# Begin SPA Emission Mask
MASK SEGMENTS=0
MASK REFERENCE MODE=0
MASK REFERENCE LEVEL=0
MASK CENTER FREQUENCY=0
**
# SPA Emission Mask Done

# Begin SPA Data
<AP    P_DATA>

** # Begin TRACE A Data **  
P_0=-103.976000 , 2884.982910 MHz  
P_1=-103.580000 , 2884.997456 MHz  
P_2=-103.748000 , 2885.012001 MHz  
P_3=-104.020000 , 2885.026547 MHz  
P_4=-103.472000 , 2885.041092 MHz  
P_5=-103.720000 , 2885.055638 MHz  
P_6=-103.752000 , 2885.070183 MHz  
P_7=-103.512000 , 2885.084729 MHz  
P_8=-103.664000 , 2885.099274 MHz  
P_9=-103.948000 , 2885.113820 MHz  
P_10=-103.720000 , 2885.128365 MHz  
P_11=-103.480000 , 2885.142911 

# Done Data $capture
# Begin SPA Emission Mask
MASK SEGMENTS=0
MASK REFERENCE MODE=0
MASK REFERENCE LEVEL=0
MASK CENTER FREQUENCY=0

# End SPA Data
<APP_DATA_END>

# End SPA Data
<APP_DATA_END>

Resultado esperado:

-103.976000   2884.982910
-103.580000   2884.997456
-103.748000   2885.012001
-104.020000   2885.026547
-103.472000   2885.041092
....
....

Nenhuma linha extra ou linhas em branco devem ser impressas, mas apenas os dados das linhas.

    
por CCC 03.05.2018 / 12:07

2 respostas

1
sed -n '/# Begin TRACE A Data/,/# Done Data $capture/{s/ MHz//;s/,/ /;s/.*=//p;}' filename
  • /pattern1/,/pattern2/ seleciona apenas as linhas do primeiro para o segundo padrão, então tudo dentro de {} é executado apenas para o intervalo
  • s/ MHz// remove a unidade à direita
  • s/,/ / substitui a vírgula por um espaço em branco
  • s/.*=//p remove tudo até o = e imprime o padrão, portanto, somente linhas no intervalo com esse = serão impressas (a opção -n suprime a saída padrão)

Na verdade, para seus dados de exemplo, você também pode fazer

sed -n 's/ MHz//;s/.*=//;s/,/ /p'

porque apenas as linhas que você deseja contêm uma vírgula.

    
por 03.05.2018 / 13:11
1

Awk solução:

awk '/# Begin TRACE A Data/{ f = 1; next }
     /# Done Data \$capture/{ f = 0 }
     NF && f{ gsub(/^P.+=|,| MHz/, ""); print }' file

A saída:

-103.976000  2884.982910  
-103.580000  2884.997456  
-103.748000  2885.012001  
-104.020000  2885.026547  
-103.472000  2885.041092  
-103.720000  2885.055638  
-103.752000  2885.070183  
-103.512000  2885.084729  
-103.664000  2885.099274  
-103.948000  2885.113820  
-103.720000  2885.128365  
-103.480000  2885.142911 
    
por 03.05.2018 / 12:15