異なるフォルダ内の複数のログファイルから文字列を抽出する

異なるフォルダ内の複数のログファイルから文字列を抽出する

親フォルダ内には多くのサブフォルダがあり、各サブフォルダ内にはログファイルがあります。ログファイルには、次のような多くのデータがあります。

>  Rotational constants (GHZ):           0.0423083           0.0029364  
> 0.0027927  Standard basis: 6-31G(d,p) (6D, 7F)  There are  1566 symmetry adapted cartesian basis functions of A   symmetry.  There are
> 1566 symmetry adapted basis functions of A   symmetry.   1566 basis
> functions,  3052 primitive gaussians,  1566 cartesian basis functions 
> 355 alpha electrons      355 beta electrons
>        nuclear repulsion energy     15971.0567247177 Hartrees.  NAtoms=  130 NActive=  130 NUniq=  130 SFac= 1.00D+00 NAtFMM=   60
> NAOKFM=T Big=T  Integral buffers will be    131072 words long. 
> Raffenetti 2 integral format.  Two-electron integral symmetry is
> turned on.  One-electron integrals computed using PRISM.  NBasis= 
> 1566 RedAO= T EigKep=  2.31D-04  NBF=  1566  NBsUse=  1566 1.00D-06
> EigRej= -1.00D+00 NBFU=  1566  Initial guess from the checkpoint file:
>     > 0.000000    0.000000    0.000000
>          Rot=    1.000000   -0.000006    0.000001   -0.000001 Ang=   0.00 deg.  Requested convergence on RMS density matrix=1.00D-08 within 128 cycles.  Requested convergence on MAX density matrix=1.00D-06. 
> Requested convergence on             energy=1.00D-06.  No special
> actions if energy rises.  SCF Done:  E(RB3LYP) =  -8526.66394979    
> A.U. after    6 cycles
>             NFock=  6  Conv=0.72D-08     -V/T= 2.0055  Calling FoFJK, ICntrl=      2127 FMM=T ISym2X=0 I1Cent= 0 IOpClX= 0 NMat=1 NMatS=1
> NMatT=0.

たとえば、SCF Done: E(RB3LYP) = -8526.66394979上記のテキストを見ています。=各ファイルの変更された値。私にとって必要なのは、すべての値を抽出して親フォルダのテキストファイルに入れることです。たとえば、bar、baz、fooという3つのフォルダがあります。今、次の結果が必要です。

bar : -8526.66394979
baz : -112232.123391
foo : 12312313:34574

次のスクリプトを実行すると、1つの値しか持たなくなります(例:-8526.66394979)。この問題を解決するのに役立ちますか?

#!/bin/bash

for file_name in *
do

cd $file_name

EE=$(grep -i 'scf done' *.log | tail -1 | awk 'NR==1 {print $5}')

echo "Electronic Energy : $EE" | column -t -s ":"  > ${file_name%%.*}.txt

mv ${file_name%%.*}.txt ../

done

ベストアンサー1

ディレクトリごとに1つのログファイルだけがあり、そのログファイルの最後の値を保持し、それをディレクトリ名とともにテキストファイルに保存する場合は、次のことを実行できます。

for dir in */; do
    grep -i 'scf done' "$dir"/*.log | 
        awk 'END{print "Electronic Energy : "$5}' |
            column -t -s ":" > "${dir///}".txt
done

たとえば、次の設定を使用しました。

$ tree
.
├── dir1
│   └── file.log
├── dir10
│   └── file.log
├── dir2
│   └── file.log
├── dir3
│   └── file.log
├── dir4
│   └── file.log
├── dir5
│   └── file.log
├── dir6
│   └── file.log
├── dir7
│   └── file.log
├── dir8
│   └── file.log
└── dir9
    └── file.log

それぞれはfile.log以下を含んでいます:

$ cat dir1/file.log 
a b scf done 123

for上記のループを実行すると、次のような結果が発生します。

$ ls *txt
dir10.txt  dir1.txt  dir2.txt  dir3.txt  dir4.txt  dir5.txt  dir6.txt  dir7.txt  dir8.txt  dir9.txt

各項目には以下が含まれます。

$ cat dir1.txt 
Electronic Energy    123

それでも問題が解決しない場合は、質問を更新し、関連するディレクトリ構造、ファイル名、サンプル入力、予想される出力を表示してください。

おすすめ記事