AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 427051
Accepted
Joshua Salazar
Joshua Salazar
Asked: 2018-02-28 15:44:49 +0800 CST2018-02-28 15:44:49 +0800 CST 2018-02-28 15:44:49 +0800 CST

Usando variáveis ​​if e shell dentro de um script awk

  • 772

Estou tentando obter dados de um arquivo que é 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 pegar sempre a quarta coluna da linha 6 (1.95329810 neste caso), então procurar seu valor mais próximo nas linhas seguintes, da primeira coluna (1.877 neste caso). Isso apenas para referenciar, depois de fundado isso, quero extrair a próxima linha cuja segunda coluna é diferente de zero (4.152).

Portanto, gostaria de obter 1,95329810 e 4,152 como saída, para poder subtraí-los e obter:

band_gap=4.152-$fermi_energy

Levando em consideração a resposta de @DopeGhoti, usei o código dele com uma instrução if:

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

Onde go.awkestá o arquivo:

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 é a maneira certa de usar variáveis ​​bash dentro de um script awk.

PD Caso você esteja se perguntando , os dados representam os cálculos da densidade de estados dos elétrons de um óxido. A primeira coluna representa as energias do elétron, a segunda a quantidade do elétron naquele nível de energia. Portanto, ao procurar o próximo valor diferente de '0,0000E+00' desde o nível mais próximo da Energia de 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)

awk data
  • 2 2 respostas
  • 435 Views

2 respostas

  • Voted
  1. Best Answer
    user1404316
    2018-02-28T19:12:55+08:002018-02-28T19:12:55+08:00

    A resposta abaixo faz uma série de mudanças em sua técnica.

    1. Faça tudo em um único awkprograma em vez de dois. Você pode fazer isso porque sua segunda execução lida apenas com linhas após a linha 6:

    2. Atribua corretamente seu valor fermi_energy da linha 6.

    3. Não é mais necessário verificar NF==3porque todas as linhas após a linha 6 atendem a esse critério.

    4. Elimine a variável teste, em vez disso, vamos manter uma guia contínua da diferença mínima entre fermi_energye $1. Para isso, criaremos uma variável minque inicialmente terá um valor ridiculamente grande, com garantia de falha no primeiro teste. Também atribuiremos nomes compreensíveis às outras variáveis ​​e imprimiremos apenas um resultado, após testar todas as linhas do arquivo.

    5. Substitua seu teste de valor absoluto computacionalmente pesado por um teste de zero computacionalmente leve.

    6. Observe que awksuporta notação científica de ponto flutuante. Por exemplo, em um printfcomando, pode-se usar o formato %E. Como de costume, consulte a manpágina ou seu mecanismo de pesquisa favorito para saber mais.

    7. Tudo isso feito sem nenhum conhecimento de física de partículas, então posso ter entendido algo errado. Perdão. Se assim for, espero que pelo menos isso o coloque no caminho certo.

      awk '
          BEGIN  { min=1000 ; jump_energy="INIT" }
          function abs(v) {return v < 0 ? -v : v}
          NR==6 {fermi_energy=$4}
          NR>6 {
              if (jump_energy != 0) {
                  this_diff=abs(fermi_energy-$1)
                  if (this_diff < min) {
                      min=this_diff
                      energy_level=0
                      jump_energy=0
                      getline
                  }
              }
              if (jump_energy == 0  && $2 != "0.0000E+00") {
                  energy_level=$1
                  jump_energy=$2
              }
          }
          END {
              printf "  Fermi Energy: %f\n  Energy Level: %f\n  Jump Energy: %E\n", fermi_energy, energy_level, jump_energy
          }'
      
    • 3
  2. Kusalananda
    2018-03-07T01:53:41+08:002018-03-07T01:53:41+08:00
    awk 'NR == 6 { fe = $4 }
         NR > 6 && $1 > fe && $2 > 0 { print fe, $1; exit }' file
    

    Para os dados de entrada fornecidos, fileisso produzirá

    1.95329810 4.152
    

    O awkscript ignora as primeiras cinco linhas de entrada. Na linha seis, ele escolhe o quarto campo e o atribui à variável fe(com exceção de "Fermi energy".

    O código então assume que os valores na coluna um estão aumentando, e quando o primeiro desses valores da primeira coluna atinge um valor acima do valor armazenado em fe, e se a segunda coluna for diferente de zero, ele imprime fee o valor da primeira coluna e sai.

    Infelizmente, não entendo totalmente seu segmento de código mais longo, pois não há explicação do que você realmente deseja que ele faça.

    • 0

relate perguntas

  • remova o número de linhas duplicadas com base na correspondência antes da primeira vírgula

  • anexar linhas após outros arquivos linha por linha

  • Como remover uma única linha entre duas linhas

  • Reorganize as letras e compare duas palavras

  • Embaralhamento de arquivo de várias linhas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve