使用 awk 解析

Posted

技术标签:

【中文标题】使用 awk 解析【英文标题】:parsing using awk 【发布时间】:2012-12-24 12:12:33 【问题描述】:

如何使用 awk 根据来自另一个文件的数据解析一个文件。

我做了一个脚本:

BEGIN FS="\t" ; OFS="\t"

while((getline<"headfpkm")>0) 
        ++a
        id[a]=$1
        fpkm[a]=$2
        print id[a],fpkm[a]
        
lastid=id[a]
print lastid
close("headfpkm")


/$lastid/
        print $2,$3,$5,$7,$8,$14,fpkm[a]
        a--
        lastid=id[a]

END print "total lines=",FNR,"\n\nfile 1 index: ",a

当我运行它时:

/$ awk -f testawk.awk file2

它正确运行 BEGIN 部​​分,但没有给出任何输出。

NM_000014       5.04503
NM_000015       0.586677
NM_000016       1.138332278
NM_000017       0.64386
NM_000018       3.61746
NM_000019       2.8793
NM_000020       10.846
NM_000021       0.685098
NM_000022       46388.6
NM_000026       0.257471
NM_000026
total lines=    10

file 1 index:   10

搜索部分有什么问题吗?

文件 2 如下所示:

34      ACADM   NM_000016       9606    hsa-miR-3148    3       80      87      0.003   -0.016  -0.094  0.082   0.112   -0.160  97
34      ACADM   NM_000016       9606    hsa-miR-3163    1       623     629     0.001   -0.022  -0.020  0.065   0.125   -0.01   57
35      ACADS   NM_000017       9606    hsa-miR-3921    3       68      75      0.013   0.192   -0.097  0.031   -0.039  -0.147  82
35      ACADS   NM_000017       9606    hsa-miR-4303    2       67      73      0.012   0.150   -0.052  0.013   -0.039  -0.036  31
35      ACADS   NM_000017       9606    hsa-miR-4653-5p 3       68      75      0.003   0.192   -0.097  0.031   -0.039  -0.157  84
37      ACADVL  NM_000018       9606    hsa-miR-124     2       31      37      0.003   0.023   -0.057  0.012   -0.032  -0.171  76
37      ACADVL  NM_000018       9606    hsa-miR-1827    2       135     141     -0.007  -0.043  -0.058  0.039   -0.069  -0.258  91
37      ACADVL  NM_000018       9606    hsa-miR-2682    2       134     140     0.003   -0.014  -0.058  0.004   -0.047  -0.232  87
37      ACADVL  NM_000018       9606    hsa-miR-449c    2       134     140     -0.035  -0.014  -0.058  0.004   -0.047  -0.270  92
37      ACADVL  NM_000018       9606    hsa-miR-506     2       31      37      -0.016  0.023   -0.057  0.012   -0.032  -0.190  80

【问题讨论】:

+1 但是您能添加一些示例输入吗?在大多数情况下,getline() 的使用应该是avoided。如果没有它,可能有一种更简单、更安全的方法可以解决您的问题。 我需要从文件中读取一列。在这个测试用例中,我只使用前 10 行数据。文件很大。还是有一种方法可以使用 sed 打印文件并将每个流作为 awk 的输入? 我了解headfpkm(以及您的while 循环)正在产生您所描述的输出。但是,如果您可以包含file2 的一些内容,将会很有帮助。您使用的方法几乎可以肯定不是这样做的方法。 【参考方案1】:

这将是一个猜测,因为我不能 100% 确定你想要完成什么。解决问题的更好方法是执行以下操作:

BEGIN 
    FS=OFS="\t"


FNR==NR 
    c++

    a[$1]=$2
    next


$3 in a 
    print $2,$3,$5,$7,$8,$14,a[$3]


END 
    printf "total lines=%s\n\nfile 1 index: %s\n", FNR, c

运行方式:

awk -f script.awk headfpkm file2

结果:

ACADM   NM_000016  hsa-miR-3148     80   87   -0.160  1.138332278
ACADM   NM_000016  hsa-miR-3163     623  629  -0.01   1.138332278
ACADS   NM_000017  hsa-miR-3921     68   75   -0.147  0.64386
ACADS   NM_000017  hsa-miR-4303     67   73   -0.036  0.64386
ACADS   NM_000017  hsa-miR-4653-5p  68   75   -0.157  0.64386
ACADVL  NM_000018  hsa-miR-124      31   37   -0.171  3.61746
ACADVL  NM_000018  hsa-miR-1827     135  141  -0.258  3.61746
ACADVL  NM_000018  hsa-miR-2682     134  140  -0.232  3.61746
ACADVL  NM_000018  hsa-miR-449c     134  140  -0.270  3.61746
ACADVL  NM_000018  hsa-miR-506      31   37   -0.190  3.61746
total lines=10

file 1 index: 10

【讨论】:

@bharat_iyengar:是的,你可以写,例如; if ($3 ~ /pattern/) ... 。请参阅我在上面所做的更新。这些是您正在寻找的结果吗? 是的,它有效。多谢。我想知道if x in y 语句是否与/$x/ 相同 如果文件 1 很大并且我不想将它保存在数组中,那么是否可以同时运行两个流?例如sed '' file1 | awk -f script file2 我认为不会,而且我认为我从未尝试过。如果$x 是一个模式,那么它就是(例如); $0 ~ $x。但通常你想测试一个变量是否等于另一个,例如:$0 == $x. 管道 (|) 符号用于将输出从一个命令传递到另一个命令。如果您希望加快处理大文件的速度,如果您有一台多核机器,我发现更好的方法是使用GNU parallel。例如,请参阅here。 HTH。

以上是关于使用 awk 解析的主要内容,如果未能解决你的问题,请参考以下文章

使用 awk 解析 /proc/pid/smaps

使用 awk 有效解析 CSV 的最可靠方法是啥?

使用 AWK 解析命名参数值

使用 bash、sed、awk 解析像 .ini 这样的文件

使用 awk 解析 nm 命令的输出 - Linux Bash

使用 awk 或 perl 从 CSV 中提取特定列(解析)