user2766886
user2766886

Reputation: 15

Awk While and For Loop

I have two files (file1 and file2)

file1:

-11.61
-11.27
-10.47

file2:

NAME
NAME
NAME

I want to use awk to search for first occurrence of NAME in file 2 and add the 1st line of file1 before it, and so on. The desired output is

########## Energy:              -11.61
NAME
########## Energy:              -11.27
NAME
########## Energy:              -10.47
NAME

I tried this code

#!/bin/bash

file=file1
while IFS= read line
do
        # echo line is stored in $line
        echo $line
awk '/MOLECULE/{print "### Energy: "'$line'}1' file2` > output
done < "$file"

But this was the output that I got

########## Energy:              -10.47
NAME
########## Energy:              -10.47
NAME
########## Energy:              -10.47
NAME

I don't know why the script is putting only the last value of file1 before each occurrence of NAME in file2.

I appreciate your help!

Sorry if I wasn't clear in my question. Here are the samples of my files (energy.txt and sample.mol2):

[user]$cat energy.txt

-11.61
-11.27
-10.47

[user]$cat sample.mol2

@<TRIPOS>MOLECULE
methane
5 4 1 0 0 
SMALL
NO_CHARGES


@<TRIPOS>ATOM
  1 C        2.8930    -0.4135    -1.3529 C.3   1 <1>   0.0000 
  2 H1       3.9830    -0.4135    -1.3529 H     1 <1>   0.0000 
  3 H2       2.5297     0.3131    -0.6262 H     1 <1>   0.0000 
  4 H3       2.5297    -1.4062    -1.0869 H     1 <1>   0.0000 
  5 H4       2.5297    -0.1476    -2.3456 H     1 <1>   0.0000 
@<TRIPOS>BOND
  1   1   2  1   
  2   1   3  1   
  3   1   4  1   
  4   1   5  1   

@<TRIPOS>MOLECULE
ammonia
4 3 1 0 0 
SMALL
NO_CHARGES


@<TRIPOS>ATOM
  1 N        8.6225    -3.5397    -1.3529 N.3   1 <1>   0.0000 
  2 H1       9.6325    -3.5397    -1.3529 H     1 <1>   0.0000 
  3 H2       8.2858    -2.8663    -0.6796 H     1 <1>   0.0000 
  4 H3       8.2858    -4.4595    -1.1065 H     1 <1>   0.0000 
@<TRIPOS>BOND
  1   1   2  1   
  2   1   3  1   
  3   1   4  1   

@<TRIPOS>MOLECULE
water
3 2 1 0 0 
SMALL
NO_CHARGES


@<TRIPOS>ATOM
  1 O        7.1376     3.8455    -3.4206 O.3   1 <1>   0.0000 
  2 H1       8.0976     3.8455    -3.4206 H     1 <1>   0.0000 
  3 H2       6.8473     4.4926    -2.7736 H     1 <1>   0.0000 
@<TRIPOS>BOND
  1   1   2  1   
  2   1   3  1

This is the output that I need

########## Energy:              -11.61
@<TRIPOS>MOLECULE
methane
5 4 1 0 0 
SMALL
NO_CHARGES


@<TRIPOS>ATOM
  1 C        2.8930    -0.4135    -1.3529 C.3   1 <1>   0.0000 
  2 H1       3.9830    -0.4135    -1.3529 H     1 <1>   0.0000 
  3 H2       2.5297     0.3131    -0.6262 H     1 <1>   0.0000 
  4 H3       2.5297    -1.4062    -1.0869 H     1 <1>   0.0000 
  5 H4       2.5297    -0.1476    -2.3456 H     1 <1>   0.0000 
@<TRIPOS>BOND
  1   1   2  1   
  2   1   3  1   
  3   1   4  1   
  4   1   5  1   
########## Energy:              -11.27
@<TRIPOS>MOLECULE
ammonia
4 3 1 0 0 
SMALL
NO_CHARGES


@<TRIPOS>ATOM
  1 N        8.6225    -3.5397    -1.3529 N.3   1 <1>   0.0000 
  2 H1       9.6325    -3.5397    -1.3529 H     1 <1>   0.0000 
  3 H2       8.2858    -2.8663    -0.6796 H     1 <1>   0.0000 
  4 H3       8.2858    -4.4595    -1.1065 H     1 <1>   0.0000 
@<TRIPOS>BOND
  1   1   2  1   
  2   1   3  1   
  3   1   4  1   
########## Energy:              -10.47
@<TRIPOS>MOLECULE
water
3 2 1 0 0 
SMALL
NO_CHARGES


@<TRIPOS>ATOM
  1 O        7.1376     3.8455    -3.4206 O.3   1 <1>   0.0000 
  2 H1       8.0976     3.8455    -3.4206 H     1 <1>   0.0000 
  3 H2       6.8473     4.4926    -2.7736 H     1 <1>   0.0000 
@<TRIPOS>BOND
  1   1   2  1   
  2   1   3  1

Upvotes: 0

Views: 211

Answers (2)

anubhava
anubhava

Reputation: 785146

Using awk:

awk 'NR==FNR{a[NR]=$0;next} /@<TRIPOS>MOLECULE/
    {print "########## Energy:             ", a[++i]}1' energy.txt sample.mol2

Explanation:

  • FNR - line number of the current file
  • NR - line number of the total lines of two files.
  • NR==FNR{a[NR]=$0;next} is applied for the first energy.txt
  • so above statement populates an array with index as 1,2,3... and value as $0
  • /@<TRIPOS>MOLECULE/ search is executed on the 2nd file sample.mol2
  • When above search is successful it prints quoted static string and a line from array created from 1st file
  • ++i moves the counter to next element in array after printing

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246807

paste -d "\n" <(sed 's/^/########## Energy:              /' file1) file2
########## Energy:              -11.61
NAME
########## Energy:              -11.27
NAME
########## Energy:              -10.47
NAME

Or, sticking with awk

awk '{
    print "########## Energy:              " $0
    getline < "file2"
    print
}' file1

Upvotes: 3

Related Questions