Bash как отфильтровать входной файл - PullRequest
0 голосов
/ 30 марта 2020

У меня довольно большой файл, содержащий много ненужных вещей, и мне нужно отфильтровать его. Итак, меня интересует вот что:

 iteration # 20     ecut=    36.00 Ry     beta=0.10
 Davidson diagonalization with overlap
 ethr =  4.07E-13,  avg # of iterations =  3.8

 total cpu time spent up to now is   351441.3 secs

 End of self-consistent calculation

 Number of k-points >= 100: set verbosity='high' to print the bands.

 highest occupied, lowest unoccupied level (ev):     2.2896    4.1062

Хорошо, поэтому мне нужно вычислить: Bg = ELUMO-EHOMO, тогда как ELUMO и EHOMO - это самые высокие и самые низкие занятые значения. Проблема в том, что я хочу получить такой вывод:

Iteration #<number>
Bg=xxx

Мои 2 вопроса: 1. Я могу выполнить grep по 'наивысшей' строке, поэтому я получаю каждую строку вроде:

 highest occupied, lowest unoccupied level (ev):     2.3005    4.0791

Но как я могу установить переменные на самый высокий и самый низкий уровень незанятости?

2. Поскольку не каждая итерация дает мне значения уровней незанятости (я хочу пропустить это затем), как я должен найти / найти иметь всегда номер итерации и незанятые уровни?

1 Ответ

1 голос
/ 30 марта 2020

Использование awk

awk '/^iteration|highest/{if ($0 ~ "iteration") gsub(/ecut.*/ , "", $0); if ($0 ~ "highest") $0=($(NF-1)-$NF); print}' 

Демо:

$cat file.txt 
iteration # 20     ecut=    36.00 Ry     beta=0.10
 Davidson diagonalization with overlap
 ethr =  4.07E-13,  avg # of iterations =  3.8

 total cpu time spent up to now is   351441.3 secs

 End of self-consistent calculation

 Number of k-points >= 100: set verbosity='high' to print the bands.

 highest occupied, lowest unoccupied level (ev):     2.2896    4.1062
$awk '/^iteration|highest/{if ($0~"iteration") gsub(/ecut.*/,"",$0); if ($0 ~ "highest") $0=($(NF-1)-$NF); print}'  < file.txt 
iteration # 20     
-1.8166
$

Объяснение:

/^iteration|highest/ -- Select only rows starting with iteration or with highesh 
($0 ~ "iteration")  -- $0 means entire row, Check if row have iteration pattern
 gsub(/ecut.*/ , "", $0) -- Delete all char after **ecut**
NF -- > number of fields in row 
$NF --> last field 
$(NF-1) --> second last field 
 $0=($(NF-1)-$NF -- Set current row as second last field -  last field
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...