2013-12-20 2 views
0

У меня есть два файла (ФАЙЛ1 и file2)Awk Хотя и For Loop

file1: 

-11.61 
-11.27 
-10.47 

file2: 

NAME 
NAME 
NAME 

Я хочу использовать AWK для поиска первого вхождения NAME в файле 2 и добавить 1-ю линию file1 перед ним, и скоро. Нужный выход

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

Я попробовал этот код

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

Но это был выход, который я получил

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

Я не знаю, почему скрипт ставит только последний значение файла1 перед каждым вхождением NAME в файл2.

Я ценю вашу помощь!

Извините, если в моем вопросе не было ясно. Вот образцы моих файлов (energy.txt и sample.mol2):

[пользователь] $ кошка energy.txt

-11.61 
-11.27 
-10.47 

[пользователь] $ кошка 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 

Это выход, который мне нужен

########## 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 
+0

Ваш вопрос будет гораздо понятнее, если вы вывесили некоторые фактические значения «NAME» в вашем входе и выходе, а не просто повторять слово " NAME "несколько раз. –

+0

Теперь, каков вам результат? –

+0

Я только что обновил требуемый выход. Спасибо – user2766886

ответ

0

Использование AWK:

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

Объяснение:

  • FNR - номер строки текущего файла
  • NR - номер строки общего количества строк двух файлов.
  • NR==FNR{a[NR]=$0;next} применяется для первого energy.txt
  • так выше заявление заполнит массив с индексом как 1,2,3... и значения, как $0
  • /@<TRIPOS>MOLECULE/ поиск выполняется на 2-ом файле sample.mol2
  • Когда над поиском успешна она печатает цитируемый статическая строка и строка из массива, созданного из 1-го файла
  • ++i перемещает счетчик на следующий элемент в массиве после печати
+0

Если у меня есть текст между шаблоном NAME и добавьте} 1 'в конец строки, чтобы распечатать все, только первое значение файла1 печатается в файле2, а NAME печатается дважды каждый раз. Извините за недостаток знаний. Я был бы признателен за помощь в этом. Спасибо! – user2766886

+0

Я могу попытаться помочь, но вам лучше понять ваши входные файлы. Вы можете отредактировать свой вопрос и предоставить этот новый формат данных inout, чтобы я мог лучше понять и исправить код. – anubhava

+0

спасибо anubhava. Я просто обновил свой вопрос с помощью улучшенных файлов примеров. – user2766886

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

Или, торчащие с AWK

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

+1, я собираюсь опубликовать одно и то же решение awk .... – Kent

+0

Если подстановка процесса недоступна, 'sed '...' file1 | paste -d "\ n" - file2' также должен работать. – chepner

+0

Работает awk-код. С другой стороны, когда я пытался использовать его в файле, который имеет некоторый текст между шаблоном NAME, возвращается только первое значение. – user2766886