원본 출력 파일에는 다음 텍스트 블록과 추가 정보가 포함되어 있습니다.
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에 사용할 수 있는 많은 테이블 형식 지정 모듈 중 하나를 사용하여 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