2

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 (_PATTERN_A_、_PATTERN_B_ など) の形式は UNII-<10 文字> です。例: UNII-4J4Z8788N8 または UNII-12L95QD6KV。
  • すべての CID に UNII があるわけではありません。

私の環境に関するメモ:

  • Windows 7 で作業しており、GnuWin32 ユーティリティを使用しています

したがって、英語で言い換えると、次のようになります。

FILE_1 内

UNII を持つすべての CID を見つける

フィルタリングされた結果を FILE_2 に送信します

事前にご指示いただきありがとうございます。

================================================== ======================

OK、私は何か間違ったことをしています。

私の最初の実装では、プログラムは「レコード開始」と「終了タグ」のみを返します。つまり:

<Information>
</Information>

これが私があなたの指示をどのように適用したかです。

まず、Windows を実行しているので FS="\r\n" に変更します

最初の正規表現は UNII なので、/UNII/ に変更します。

2 番目の正規表現は、指示で使用した CID です。私はそこに変更を加えませんでした。

PATTERN の 2 番目のインスタンスでは、/UNII/ に変更しました。

これが私の置換の外観です。

BEGIN {
    RS="<Information>"
    FS="\r\n"
}
/UNII/ {
    print RS
    for (i=1;i<NF;i++) {
        if ($i ~ /CID/ || $i ~ /UNII/) {
            print $i
        }
    }
    print "</Information>"
}

私は Windows を使用しているため、フル パスを使用して GnuWin32 ユーティリティを実行し、データを読み書きします。したがって、私の .bat ファイルは次のようになります。

C:\bin\awk -f C:\bin\script.awk < C:\Users\Owner\data\input_file.txt > C:\Users\Owner\data\output_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>
4

2 に答える 2

1

まず、awk はこれには完全に不適切なツールです。ただし、awk でこれを行う最も簡単な方法は、(必要な行を選択するのではなく) 必要のない行を抑制することです。

/Synonym/ && !/UNII/ { next }
{ print }
于 2013-04-28T16:06:14.440 に答える