ソース出力ファイルには、次のテキストブロックと追加情報が含まれています。
Projecting out rotations and translations
Force Constants (Second Derivatives of the Energy) in [a.u.]
GX1 GY1 GZ1 GX2 GY2
GX1 0.6941232
GY1 0.0187624 0.0156533
GZ1 -0.1175495 -0.0980708 0.6144300
GX2 -0.6074291 -0.0036667 0.0229726 0.6228918
GY2 0.0069881 -0.0013581 0.0085087 0.0023190 0.0014047
GZ2 -0.0437815 0.0085087 -0.0533084 -0.0145287 -0.0088007
GX3 -0.0866941 -0.0150957 0.0945769 -0.0154627 -0.0093070
GY3 -0.0257505 -0.0142952 0.0895621 0.0013477 -0.0000466
GZ3 0.1613309 0.0895621 -0.5611216 -0.0084438 0.0002920
GZ2 GX3 GY3 GZ3
GZ2 0.0551377
GX3 0.0583102 0.1021568
GY3 0.0002920 0.0244027 0.0143418
GZ3 -0.0018293 -0.1528871 -0.0898540 0.5629509
これまで、関連ヘッダーと一緒に必要なデータを正常に分離し、[grep]と[awk](下)を使用してログファイルに印刷しました。
#!/bin/bash
rm Hessian.log
for i in *.out
do
grep -H -A16 "Force Constants (Second Derivatives of the Energy)" $i | tail -n +1 | awk ' NR == 2 {printf " "" %10s %10s %10s %10s %10s \n", $2,$3,$4,$5,$6} NR == 3, NR == 11 {printf "%5s %10s %10s %10s %10s %10s\n", $2,$3,$4,$5,$6,$7} ' >> Hessian.log
echo "" >> Hessian.log
done
次を生成します。
GX1 GY1 GZ1 GX2 GY2
GX1 0.6941232
GY1 0.0187624 0.0156533
GZ1 -0.1175495 -0.0980708 0.6144300
GX2 -0.6074291 -0.0036667 0.0229726 0.6228918
GY2 0.0069881 -0.0013581 0.0085087 0.0023190 0.0014047
GZ2 -0.0437815 0.0085087 -0.0533084 -0.0145287 -0.0088007
GX3 -0.0866941 -0.0150957 0.0945769 -0.0154627 -0.0093070
GY3 -0.0257505 -0.0142952 0.0895621 0.0013477 -0.0000466
GZ3 0.1613309 0.0895621 -0.5611216 -0.0084438 0.0002920
GZ2 GX3 GY3 GZ3
GZ2 0.0551377
GX3 0.0583102 0.1021568
GY3 0.0002920 0.0244027 0.0143418
GZ3 -0.0018293 -0.1528871 -0.0898540 0.5629509
ただし、最後の4行を上のデータの横の列に移動し、そのヘッダー(GZ2、GX3、GY3、GZ3)が他のヘッダーと同じ行になるように移動しようとしています。簡単に言えば、結果の出力は、各列と行のラベル付き9 * 9データ行列でなければなりません(下記参照)。
GX1 GY1 GZ1 GX2 GY2 GZ2 GX3 GY3 GZ3
GX1 0.6941232
GY1 0.0187624 0.0156533
GZ1 -0.1175495 -0.0980708 0.6144300
GX2 -0.6074291 -0.0036667 0.0229726 0.6228918
GY2 0.0069881 -0.0013581 0.0085087 0.0023190 0.001404
GZ2 -0.0437815 0.0085087 -0.0533084 -0.0145287 -0.0088007 0.0551377
GX3 -0.0866941 -0.0150957 0.0945769 -0.0154627 -0.0093070 0.0583102 0.1021568
GY3 -0.0257505 -0.0142952 0.0895621 0.0013477 -0.0000466 0.0002920 0.0244027 0.0143418
GZ3 0.1613309 0.0895621 -0.5611216 -0.0084438 0.0002920 -0.0018293 -0.1528871 -0.0898540 0.5629509
答え1
単純なPerlスクリプトはこれをうまく行います(Perlはほぼどこにでもインストールされます)。
#!/usr/bin/env perl
my @rows; # Preserve order of appearance
my %rows;
my $heading;
for (<>) {
chomp;
if (s/^\s+/ /) {
$heading .= $_;
} elsif (/^(\w+) (.*)$/) {
push @rows, $1 if not exists $rows{$1};
$rows{$1} .= $2;
} else {
die "Invalid line format at line $.";
}
}
my $fmt = "%-5s %s\n"; # Adjust width to suit taste
printf $fmt, '', $heading;
printf $fmt, $_, $rows{$_} for @rows;
次のようにデータを使用してプログラムを呼び出すだけです。
$ my_column.pl < your_data.txt
(もちろん、上記のスクリプトを別の名前で保存しmy_column.pl
て実行可能にするものとします。chmod 755 my_column.pl
)
上記の作業を実行する必要がありますが、正確な列ソートまたは高度な書式設定が必要な場合は、Perlで使用できる多くのテーブル書式設定モジュールの1つを使用して列を設定し、特定split
の列幅を強制できます。printf
答え2
私の問題を解決しました。特定の行と列を変数として代入し、エコーを使用してリンクします。答えを知るのは簡単です!
#!/bin/bash
cd FREQ/HF
rm Hessian.log
for i in *.out
do
grep -H -A16 "Force Constants (Second Derivatives of the Energy)" $i | tail -n +1 >> Hessian.tmp
x=`awk ' NR == 2 {printf " "" %10s %10s %10s %10s %10s \n", $2,$3,$4,$5,$6}' Hessian.tmp`
y=`awk ' NR == 12 {printf "%10s %10s %10s %10s \n", $2,$3,$4,$5}' Hessian.tmp`
a=`awk ' NR == 8 { printf "%5s %10s %10s %10s %10s %10s\n", $2,$3,$4,$5,$6,$7} ' Hessian.tmp`
b=`awk ' NR == 9 { printf "%5s %10s %10s %10s %10s %10s\n", $2,$3,$4,$5,$6,$7} ' Hessian.tmp`
c=`awk ' NR == 10 { printf "%5s %10s %10s %10s %10s %10s\n", $2,$3,$4,$5,$6,$7} ' Hessian.tmp`
d=`awk ' NR == 11 { printf "%5s %10s %10s %10s %10s %10s\n", $2, $3,$4,$5,$6,$7} ' Hessian.tmp`
e=`awk ' NR == 13 { printf "%10s", $3} ' Hessian.tmp`
f=`awk ' NR == 14 { printf "%10s %10s", $3, $4} ' Hessian.tmp`
g=`awk ' NR == 15 { printf "%10s %10s %10s", $3, $4,$5} ' Hessian.tmp`
h=`awk ' NR == 16 { printf "%10s %10s %10s %10s", $3, $4, $5,$6} ' Hessian.tmp`
echo "$x $y" >> Hessian.log
awk '
NR == 3, NR == 7 {printf "%5s %10s %10s %10s %10s %10s\n", $2,$3,$4,$5,$6,$7} ' Hessian.tmp >> Hessian.log
echo "$a $e" >> Hessian.log
echo "$b $f" >> Hessian.log
echo "$c $g" >> Hessian.log
echo "$d $h" >> Hessian.log
rm Hessian.tmp
echo "" >> Hessian.log
done