ある行のテキストを別の行の末尾に追加するには?

ある行のテキストを別の行の末尾に追加するには?

ソース出力ファイルには、次のテキストブロックと追加情報が含まれています。

 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

関連情報