首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >awk -如何提取模式

awk -如何提取模式
EN

Stack Overflow用户
提问于 2013-04-28 11:31:46
回答 2查看 718关注 0票数 2

询问有关使用awk从文件中提取具有特定行的文本块的说明。

该文件具有以下结构:

代码语言:javascript
复制
<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将以下模式发送到新文件。

代码语言:javascript
复制
<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-<10 characters>。例如:UNI-4J4Z8788N8或UNII-12L95QD6KV。
  • 不是每个CID都有一个UNII。

关于我的环境的笔记:

  • 我在Windows 7下工作,并使用GnuWin32实用程序

因此,用英语重新措辞:

在FILE_1中 找到每一个有UNII的CID 将过滤后的结果发送到FILE_2

谢谢您的指示。

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

好吧,我做错了什么。

在我的第一个实现中,程序只返回“记录开始”和“结束标记”,即:

代码语言:javascript
复制
<Information>
</Information>

这是我如何运用你的指示。

首先,我运行的Windows被更改为FS="\r\n“

第一个正则表达式是UNII,它被更改为/UNII/。

第二个正则表达式是CID,您在说明中使用了CID。我在那里没做任何改变。

对于模式的第二个实例,我更改为/UNII/。

以下是我的替代品:

代码语言:javascript
复制
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文件如下所示:

代码语言:javascript
复制
C:\bin\awk -f C:\bin\script.awk < C:\Users\Owner\data\input_file.txt > C:\Users\Owner\data\output_file.txt

我做错了什么?

=================================================================================这里是示例数据:

代码语言:javascript
复制
<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>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-28 13:22:11

这个脚本应该提供一个很好的起点:

代码语言:javascript
复制
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并在示例输入上运行它会产生:

代码语言:javascript
复制
$ 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>
票数 1
EN

Stack Overflow用户

发布于 2013-04-28 16:06:14

首先,awk是完全错误的工具。但是,使用awk实现这一点的最简单方法是抑制不想要的行(而不是选择想要的行):

代码语言:javascript
复制
/Synonym/ && !/UNII/ { next }
{ print }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16262401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档