Lidar com instruções e variáveis com awk

0

Estou tentando obter dados de um arquivo assim:

  6   6   1   0
  0.1166667E+02  0.4826611E-09  0.4826611E-09  0.3004786E-09  0.5000000E-15
  1.000000000000000E-004
  CAR 
 system-001                       
     10.51965443    -34.96542345  301      1.95329810      1.00000000
-15.558  0.1631E+01  0.1597E+02
-15.407  0.1661E+02  0.1779E+02
-15.255  0.4253E+01  0.1990E+02
-15.104  0.0000E+00  0.2000E+02
-14.952  0.0000E+00  0.2000E+02
 -3.884  0.0000E+00  0.2000E+02
 -3.732  0.0000E+00  0.2000E+02
 -3.581  0.0000E+00  0.2000E+02
 -3.429  0.0000E+00  0.2000E+02
 -3.277  0.8214E-03  0.2000E+02
 -3.126  0.3543E+00  0.2002E+02
  1.726  0.1019E+01  0.4386E+02
  1.877  0.5581E+00  0.4399E+02
  2.029  0.0000E+00  0.4400E+02
  2.181  0.0000E+00  0.4400E+02
  2.332  0.0000E+00  0.4400E+02
  2.484  0.0000E+00  0.4400E+02
  2.636  0.0000E+00  0.4400E+02
  2.787  0.0000E+00  0.4400E+02
  2.939  0.0000E+00  0.4400E+02
  3.090  0.0000E+00  0.4400E+02
  3.242  0.0000E+00  0.4400E+02
  3.394  0.0000E+00  0.4400E+02
  3.545  0.0000E+00  0.4400E+02
  3.697  0.0000E+00  0.4400E+02
  3.849  0.0000E+00  0.4400E+02
  4.000  0.0000E+00  0.4400E+02
  4.152  0.6271E-01  0.4400E+02
  4.303  0.4520E+01  0.4433E+02
  4.455  0.5040E+01  0.4511E+02

Eu quero levar sempre a quarta coluna da linha 6 (1.95329810 neste caso), então procure por seu valor mais próximo nas linhas a seguir, da primeira coluna (1.877 neste caso). Isso só para referenciamento, após fundar isso, quero extrair a próxima linha que sua segunda coluna é diferente de zero (4.152).

Então eu gostaria de obter 1.95329810 e 4.152 como saída, para que eu possa subtraí-los e obter:

band_gap=4.152-$fermi_energy

Ao considerar a resposta do @DopeGhoti, usei o código dele com uma declaração if:

#!/bin/bash
fermi_energy=$(awk 'NR==6 {printf $4}' DOSCAR-62.4902421.st)
awk -f go.awk DOSCAR-62.4902421.st

Onde o arquivo go.awk é:

BEGIN { 
test=0
}
NF == 3 && test == 0 && $2 != "0.0000E+00" {
   keptvalue=$1
}
NF == 3 && test == 0 && $2 == "0.0000E+00" {
   #print keptvalue
   test=1
}
NF == 3 && test == 1 && $2 != "0.0000E+00" {
   if ( sqrt(($fermi_energy-$1)**2) < 0.5 ) 
   {
       print $1
       test=0
   }
}

Mas acho que não é o jeito certo de usar variáveis bash dentro de um script awk.

P.D. Caso você esteja se perguntando , os dados representam os cálculos da Densidade de estados do elétrons de um óxido. A primeira coluna representa as energias do elétron, a segunda a quantidade do elétron nesse nível de energia. Portanto, ao procurar o próximo valor não '0.0000E + 00' desde o nível mais próximo da Energia Fermi , podemos calcular a energia necessária para fazer os elétrons saltarem e conduzirem eletricidade. (Metais têm gap zero, portanto não precisam de entrada de energia para conduzir eletricidade)

    
por Joshua Salazar 26.02.2018 / 20:52

1 resposta

2

Isso parece fazer o que você parece querer, dada a falta de saída de amostra:

awk 'NF == 3 && $2 != "0.0000E+00" { print $1 }' /path/to/input
1.726
1.877
4.152
4.303
4.455

Se você está realmente pedindo o primeiro campo na última linha onde o segundo campo é não (matematicamente) zero, o qual é seguido por um registro onde o segundo campo é (matematicamente) zero, seguido apenas pelo primeiro campo do primeiro registro subseqüente, onde o segundo campo é novamente não (matematicamente) zero .. isso também é possível com um script relativamente simples awk :

$ cat go.awk
BEGIN { 
  test=0
}

NF == 3 && test == 0 && $2 != "0.0000E+00" {
  keptvalue=$1
}

NF == 3 && test == 0 && $2 == "0.0000E+00" {
  print keptvalue
  test=1
}

NF == 3 && test == 1 && $2 != "0.0000E+00" {
  print $1
  test=0
}
$ awk -f go.awk input
1.877
4.152
    
por 26.02.2018 / 21:28