Como eu adiciono texto de uma linha ao final de outra?

4

O arquivo de saída original continha este bloco de texto entre muito mais informações:

 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

Até agora eu consegui isolar os dados que eu preciso junto com os cabeçalhos relevantes, e imprimi-los em um arquivo de log usando [grep] e [awk] (abaixo):

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

Que produz:

          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

No entanto, estou tentando mover as últimas quatro linhas para que elas fiquem em colunas próximas aos dados acima, com seus respectivos títulos (GZ2, GX3, GY3, GZ3) na mesma linha que os outros títulos. Para simplificar, a saída resultante deve ser uma matriz 9 * 9 de dados com rótulos para cada coluna e linha (como mostrado abaixo).

          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
    
por Stephen Mason 07.12.2016 / 23:41

2 respostas

0

Gerenciado para resolver meu próprio problema simplesmente atribuindo a linha e coluna específicas como uma variável, e concatenando-as usando echo, simples quando você sabe a resposta!

#!/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
    
por 10.12.2016 / 13:21
2

Um simples script Perl fará o truque bem (o Perl já está instalado no dang perto de tudo):

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

Basta invocar este programa com seus dados assim:

$ my_column.pl < your_data.txt

(Supondo que você salvou o script acima como my_column.pl e tornou executável com chmod 755 my_column.pl , é claro!)

As etapas acima devem executar o trabalho, mas se você precisar de alinhamento preciso de colunas ou formatação mais avançada em geral, poderá split das colunas e forçar determinadas larguras de colunas com printf ou um dos muitos módulos de formatação tabulares disponível para Perl.

    
por 08.12.2016 / 02:11