awk-как извлечь шаблон
Запрашивает инструкции по использованию awk для извлечения текстовых блоков с определенными строками из файла.
Файл имеет следующую структуру:
<Information>
<CID>_whole_number_A_</CID>
<string>_text_that_is_not_useful_</string>
<string>_text_that_is_not_useful_</string>
<string>_PATTERN_A_</string>
<string>_text_that_is_not_useful_</string>
</Information>
<Information>
<CID>_whole_number_B_</CID>
<string>_PATTERN_B_</string>
<string>_text_that_is_not_useful_</string>
<string>_text_that_is_not_useful_</string>
<string>_text_that_is_not_useful_</string>
<string>_text_that_is_not_useful_</string>
<string>_text_that_is_not_useful_</string>
</Information>
Хотел бы awk отправить следующий шаблон в новый файл.
<Information>
<CID>_whole_number_A_</CID>
<string>_PATTERN_A_</string>
</Information>
<Information>
<CID>_whole_number_B_</CID>
<string>_PATTERN_B_</string>
</Information>
Примечания к данным:
- файл содержит 300 000 + элементов CID; каждый идентифицируется с уникальным целым число.
- паттерны (_PATTERN_A, _PATTERN_B_ и т. д.) есть формат UNII - . Например: UNII-4J4Z8788N8 или UNII-12L95QD6KV.
- не каждый CID имеет UNII.
Заметки о моем окружении:
- я работаю под Windows 7 и использую утилиты GnuWin32
Итак, перефразируя по-английски:
В файле FILE_1
Найти каждый CID, который имеет UNII
Отправьте отфильтрованные результаты в FILE_2
Заранее спасибо за инструкции.
========================================================================
Хорошо, я делаю что-то не так.В моей первой реализации программа возвращает только "запись начинается" и "закрывающий тег", т. е.:
<Information>
</Information>
Вот как я применил ваши инструкции.
Во-первых, я запускаю Windows, поэтому изменил FS= "rn "
Первое регулярное выражение унии, так изменилось к /унии/.
Вторым регулярным выражением является CID, которое вы используется в ваших инструкциях. Там я ничего не менял.
Для второго экземпляра шаблона я изменил значение на / UNII/.
Вот как выглядят мои замены:
BEGIN {
RS="<Information>"
FS="rn"
}
/UNII/ {
print RS
for (i=1;i<NF;i++) {
if ($i ~ /CID/ || $i ~ /UNII/) {
print $i
}
}
print "</Information>"
}
Поскольку я использую Windows, я использую полный путь для выполнения утилит GnuWin32 и чтения/записи данных. Так что мой .файл bat выглядит следующим образом:
C:binawk -f C:binscript.awk < C:UsersOwnerdatainput_file.txt > C:UsersOwnerdataoutput_file.txt
Что я делаю не так?
================================================================================= Вот примерные данные:
<Information>
<CID>1</CID>
<Synonym>Acetyl carnitine</Synonym>
<Synonym>O-Acetyl-L-carnitine</Synonym>
<Synonym>Ammonium, (3-carboxy-2-hydroxypropyl)trimethyl-, hydroxide, inner salt, acetate, DL-</Synonym>
<Synonym>UNII-07OP6H4V4A</Synonym>
<Synonym>_20+_more_</Synonym>
</Information>
<Information>
<CID>10006</CID>
<Synonym>HYDANTOIN</Synonym>
<Synonym>UNII-I6208298TA</Synonym>
<Synonym>53760_FLUKA</Synonym>
<Synonym>NSC9226</Synonym>
<Synonym>_20+_more_</Synonym>
</Information>
<Information>
<CID>10007</CID>
<Synonym>Lucofen SA</Synonym>
<Synonym>461-78-9</Synonym>
<Synonym>EINECS 207-314-9</Synonym>
<Synonym>STK664067</Synonym>
<Synonym>DEA No. 1645</Synonym>
<Synonym>UNII-NHW07912O7</Synonym>
<Synonym>CHEMBL1201269</Synonym>
<Synonym>HMS1376E21</Synonym>
<Synonym>_20+_more_</Synonym>
</Information>
2 ответа:
Этот сценарий должен обеспечить хорошую отправную точку:
BEGIN { RS="<Information>" FS="\n" } /UNII/ { print RS for (i=1;i<NF;i++) { if ($i ~ /CID/ || $i ~ /UNII/) { print $i } } print "</Information>" }
Сохранение его в
script.awk
и запуск его на входе образца производит:$ awk -f script.awk file <Information> <CID>1</CID> <Synonym>UNII-07OP6H4V4A</Synonym> </Information> <Information> <CID>10006</CID> <Synonym>UNII-I6208298TA</Synonym> </Information> <Information> <CID>10007</CID> <Synonym>UNII-NHW07912O7</Synonym> </Information>