如何将一行中的文本附加到另一行的末尾?

如何将一行中的文本附加到另一行的末尾?

原始输出文件包含此文本块以及更多信息:

 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

但是,我试图移动最后四行,以便它们位于上面数据旁边的列中,其各自的标题(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 可用的许多表格格式化模块之一split来设置列并强制特定的列宽。printf

答案2

设法解决我自己的问题,只需将特定的行和列分配为变量,并使用 echo 连接它们,当您知道答案时就很简单!

#!/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

相关内容