代码之家  ›  专栏  ›  技术社区  ›  bapors

抓取两列之间的所有匹配项

  •  0
  • bapors  · 技术社区  · 7 年前

    1st columns 并附加 2nd column 属于 file2.txt 到底 file1.txt

    file1.txt
    NC_000008.10    1264       5646      G_synym=E4566
    NC_000008.10    1264       5646      G=AGO2
    NC_000008.10    5584       5646      G=AGO2
    NC_000008.10    5218       5410      G=AGO2
    NC_000008.10    2911       3031      G=AGO2
    NC_000008.10    2552       2733      G=AGO2
    NC_000008.10    0473       0609      G=AGO2
    NC_000008.10    9494       9628      G=AGO2
    NC_000008.10    8584       8671      G=AGO2
    NC_000008.10    7188       7335      G=AGO2
    
    
    file2.txt
    NC_000001.10    chr1
    NC_000002.11    chr2
    NC_000003.11    chr3
    NC_000004.11    chr4
    NC_000005.9     chr5
    NC_000006.11    chr6
    NC_000007.13    chr7
    NC_000008.10    chr8
    NC_000009.11    chr9
    NC_000010.10    chr1 
    

    awk 'NR==FNR { a[$1] = $0; next }($1) in a { print a[$1], $2 }' file1.txt file2.txt
    

    这将产生以下输出:

    NC_000008.10    7188       7335      G=AGO2 chr8
    

    它只是随机打印其中一个匹配项。

    但预期产出将是:

    NC_000008.10    1264       5646      G_synym=E4566  chr8
    NC_000008.10    1264       5646      G=AGO2  chr8
    NC_000008.10    5584       5646      G=AGO2  chr8
    NC_000008.10    5218       5410      G=AGO2  chr8
    NC_000008.10    2911       3031      G=AGO2  chr8
    NC_000008.10    2552       2733      G=AGO2  chr8
    NC_000008.10    0473       0609      G=AGO2  chr8
    NC_000008.10    9494       9628      G=AGO2  chr8
    NC_000008.10    8584       8671      G=AGO2  chr8
    NC_000008.10    7188       7335      G=AGO2  chr8
    

    我该怎么做 awk 是否打印所有匹配项,而不是仅打印一项?

    3 回复  |  直到 7 年前
        1
  •  2
  •   Inian    7 年前

    您应该在中使用的代码 Awk 应该是

    awk 'FNR == NR { hash[$1] = $2; next } $1 in hash { NF++; $NF = hash[$1] }1' file2 file1
    

    file2 我们将第一列中的值与第二列中的值进行散列。当我们穿过 file1 ,为了匹配散列索引中的值,我们引入了一个新列来存储散列值。 NF++ 基本上是将文件中的列数增加1,因为我们引入了一个包含哈希值的新列。

    要使命令的输出更加格式化,请将输出分隔符设为“到”选项卡 OFS="\t" awk column -t .

        2
  •  2
  •   karakfa    7 年前

    如果文件按键排序,最简单的是

    $ join -a1 file1 file2 | column -t
    
    NC_000008.10  1264  5646  G_synym=E4566  chr8
    NC_000008.10  1264  5646  G=AGO2         chr8
    NC_000008.10  5584  5646  G=AGO2         chr8
    NC_000008.10  5218  5410  G=AGO2         chr8
    NC_000008.10  2911  3031  G=AGO2         chr8
    NC_000008.10  2552  2733  G=AGO2         chr8
    NC_000008.10  0473  0609  G=AGO2         chr8
    NC_000008.10  9494  9628  G=AGO2         chr8
    NC_000008.10  8584  8671  G=AGO2         chr8
    NC_000008.10  7188  7335  G=AGO2         chr8
    

    column -t a1

        3
  •  1
  •   Tyl    7 年前

    awk 'NR==FNR{a[$1]=$2;next}$1 in a{$(++NF)=a[$1]}1' file2.txt file1.txt
    

    您应该先读取文件2,然后读取文件1。

    然而,你的问题有点模棱两可,你没有说 not matched 行是否应该打印。

    awk 'NR==FNR{a[$1]=$2;next}$1 in a{$(++NF)=a[$1];print}' file2.txt file1.txt
    

    另一件事是,输出字段用一个空格分隔。由于您的输入文件似乎格式良好,因此您可能需要 -v OFS="\t" 将输出与输出分开 TAB .

    注意:如果文件2可能为空,则应更改 NR==FNR 不同的文件检查方法,如 ARGIND==1 FILENAME=="file2.txt" FILENAME==ARGV[1]

    检查文件,这基本上意味着第一次读取文件( file2.txt
    a 是存储file1.txt第2行的数组,使用其第1行作为键。
    $1 in a 看看是否 $1 存在于数组中 A. a[$1] 如果需要,请检查该值。当您确定该值不会为空时,可以互换使用。)
    ++NF 将字段数增加1。 $NF 表示最后一列。所以
    $(++NF) 的最后一列。
    最后裸露 1 这只是一个简单的问题 true {print}