다음과 같은 파일에서 데이터를 가져오려고 합니다.
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
나는 항상 행 6(이 경우 1.95329810)에서 네 번째 열을 가져온 다음 다음 행의 첫 번째 열(이 경우 1.877)에서 가장 가까운 값을 찾고 싶습니다. 이것은 단지 참조용이며 일단 발견되면 두 번째 열이 0이 아닌 다음 행(4.152)을 추출하고 싶습니다.
그래서 나는 1.95329810과 4.152를 출력으로 얻고 이를 빼서 다음을 얻을 수 있습니다.
band_gap=4.152-$fermi_energy
@DopeGhoti의 답변을 고려하여 if 문과 함께 그의 코드를 사용했습니다.
#!/bin/bash
fermi_energy=$(awk 'NR==6 {printf $4}' DOSCAR-62.4902421.st)
awk -f go.awk DOSCAR-62.4902421.st
파일 위치 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
}
}
하지만 이것은 awk 스크립트에서 bash 변수를 사용하는 올바른 방법이 아니라고 생각합니다.
PD알고 싶다면, 데이터는 계산을 나타냅니다상태 밀도산화물 전자. 첫 번째 열은 전자의 에너지를 나타내고, 두 번째 열은 해당 에너지 준위의 전자 수를 나타냅니다. 따라서 가장 가까운 레벨 이후 "0.0000E+00"이 아닌 다음 값을 찾을 때페르미 에너지, 우리는 전자가 점프하여 전기를 전도하는 데 필요한 에너지를 계산할 수 있습니다. (금속은 밴드갭이 0이므로 전기를 전도하는 데 에너지 입력이 필요하지 않습니다.)
답변1
아래 답변은 기술을 일부 변경합니다.
awk
두 개가 아닌 하나의 프로그램으로 모든 작업을 수행하세요. 두 번째 실행에서는 행 6 이후의 행만 처리하기 때문에 이렇게 할 수 있습니다.6행에 fermi_energy 값을 올바르게 할당합니다.
더 이상 확인할 필요가 없기
NF==3
때문에모두6행 이후의 행은 이 기준을 충족합니다.변수를 제거 하고 대신에 및 실행 중인 tabs 사이의 최소한의 차이를
test
유지합시다 . 이를 위해 처음에는 첫 번째 테스트에서 실패할 것으로 보장되는 터무니없이 큰 값을 갖는 변수를 생성합니다. 또한 다른 변수에도 이해하기 쉬운 이름을 할당하고 테스트 파일의 모든 줄 다음에 하나의 결과만 인쇄합니다.fermi_energy
$1
min
계산적으로 비용이 많이 드는 절대값 테스트를 계산적으로 저렴한 제로 테스트로 대체합니다.
부동
awk
소수점 과학 표기법이 지원됩니다. 예를 들어,printf
명령에서 format 을 사용할 수 있습니다 . 항상 그렇듯이 자세한 내용은 해당 페이지나 즐겨 사용하는 검색 엔진을%E
확인하세요 .man
이 모든 작업은 입자 물리학에 대해 전혀 모르는 상태에서 수행되었으므로 뭔가 잘못된 정보를 얻었을 수도 있습니다. 뭐라고요. 그렇다면 적어도 이것이 당신을 올바른 길로 인도하기를 바랍니다.
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 }'
답변2
awk 'NR == 6 { fe = $4 }
NR > 6 && $1 > fe && $2 > 0 { print fe, $1; exit }' file
주어진 입력 데이터에 대해 file
다음을 생성합니다.
1.95329810 4.152
스크립트 awk
는 입력의 처음 5줄을 무시합니다. 6번째 줄에서는 네 번째 필드를 선택하여 변수 fe
(간단히 "페르미 에너지")에 할당합니다.
그런 다음 코드는 첫 번째 열의 값이 증가한다고 가정하고 첫 번째 열의 첫 번째 값이 에 저장된 값보다 큰 값에 도달할 때 fe
두 번째 열이 0이 아니면 값 fe
을 출력합니다. 첫 번째 열 값 열을 내보내고 내보냅니다.
불행히도 나는 그렇지 않습니다.완전히실제로 수행하려는 작업에 대한 설명이 없으므로 긴 코드 조각을 이해하십시오.