awk - 在file2

时间:2017-11-17 14:39:37

标签: bash awk

我有一个代码从file1读取基因名称并在file2中找到它们,然后我把它们放在一个表中,我的问题是我需要添加另一个列与关联的" start"从file1到表的值,但无法成功。我已经尝试过了,但我不是第一时间对awk了解得太多,所以欢迎任何帮助。

决赛桌的想法是:

File1_gen  File2_gen  Start_from_file1  Value_1_from_file2  Value_2_from_file2

文件1: 该文件有~70.000行和4列;行号,基因名称,基因起始和基因结束,我只需要基因名称并从此开始

        seqnames    start   end
10  Gen_3992149.1   851 900
11  Gen_0011774.1   3899    4043
12  Gen_0011774.1   7628    7692
13  Gen_3993605.1   522 535

文件2: 然后,第二个文件有~100,000行和3列;基因名称,起始值和结束值,我需要其中的三个

Gen_3993605.1   1   602
Gen_3989779.1   691 1002
Gen_3989835.1   1   993
Gen_0011774.1   1476    1712
Gen_0011774.1   5125    6931
Gen_0011774.1   8838    12313

我已经有了一个伪代码几乎完成了所有这些

awk '
FNR == NR {
  # reading file1
    scaf[$2] 
    co_id[$3]
next
}
{
  # reading file2
  for (i in scaf) {
    id in co_id
    if ( i == $1 )
    print "[1] "  i "\t" "[2] " $1 "\t" "[3] " id "\t" "[4] " $4 "\t" "[5] "$5
    }
       }
 ' Search.txt Genes.txt

导致这样的事情:

[1] Gen_3993605.1       [2] Gen_3993605.1       [3] 522    [4] 1    [5] 602
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 3899    [4] 1476    [5] 1712
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 3899    [4] 5125    [5] 6931
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 3899    [4] 8838    [5] 12313
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 7628    [4] 1476    [5] 1712
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 7628    [4] 5125    [5] 6931
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 7628    [4] 8838    [5] 12313

如您所见,[3]列为空,我知道co_id'中的' ID是错的,但这是我尝试的最后一次尝试。

换句话说,如何调用相关的" start" file1中每个基因的值是否已进入新表?

编辑:更改了应该工作的示例数据。如果有重复的基因名称,它应该显示所有组合。

3 个答案:

答案 0 :(得分:1)

第二次尝试......基于更新的问题,a)减少数据集; b)支持基因名称在数据文件中出现多次的额外要求。

示例数据:

$ cat gene.1
10  Gen_3992149.1   851 900
11  Gen_0011774.1   3899    4043
12  Gen_0011774.1   7628    7692
13  Gen_3993605.1   522 535

$ cat gene.2
Gen_3993605.1   1   602
Gen_3989779.1   691 1002
Gen_3989835.1   1   993
Gen_0011774.1   1476    1712
Gen_0011774.1   5125    6931
Gen_0011774.1   8838    12313

另一个awk解决方案:

$ awk '
# process first file; use gene name and row number as indices for 2-dimensional array;
# $2=gene/name, $1=row/number, $3=start/value
FNR==NR { start[$2][$1]=$3
          next }

# process second file
{ # loop through list of first dimension indices (ie, gene names)
  for (x in start)
      # if gene name ($1) shows up as first dimension index in our array ...
      if ( $1==x)
         # loop through the associated 2nd dimension, printing the desired results
         { for (y in start[x])
               { print "[1] " x "\t" "[2] " x "\t" "[3] " start[x][y] "\t" "[4] " $2 "\t" "[5] "$3 }
         }
} ' gene.1 gene.2 | sort

[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 3899        [4] 1476        [5] 1712
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 3899        [4] 5125        [5] 6931
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 3899        [4] 8838        [5] 12313
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 7628        [4] 1476        [5] 1712
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 7628        [4] 5125        [5] 6931
[1] Gen_0011774.1       [2] Gen_0011774.1       [3] 7628        [4] 8838        [5] 12313
[1] Gen_3993605.1       [2] Gen_3993605.1       [3] 522 [4] 1   [5] 602

注意:通过sort管道传输结果进行基本排序;可以根据所需的输出修改排序标准

正如我之前的回答中所提到的:如果输出需要以固定宽度列显示,那么可以通过用适当的print格式字符串替换printf来实现。 (或者,使用@ karakfa&column命令的示例。)

答案 1 :(得分:0)

注意:这个答案基于原始问题,这个问题需要我创建一些样本测试数据;原始问题也没有提到基因名称可能在任一数据文件中多次出现。

一些示例数据:

$ cat gene.1
1   Gen_3989161.1   696 720
2   Gen_3989469.1   693 733
3   Gen_3989837.1   462 515
4   Gen_3990203.1   27  112
5   Gen_3990467.1   476 481
6   Gen_3991323.1   134 152
7   Gen_3991401.1   597 681
8   Gen_3991403.1   175 217
9   Gen_3991951.1   897 907
10  Gen_6899912.3   888 999

$ cat gene.2
Gen_3989161.1   1696 2720
Gen_3989469.1   1693 2733
Gen_3989837.1   1462 2515
Gen_3990203.1   127  2112
Gen_3990467.1   1476 2481
Gen_3991323.1   1134 2152
Gen_3991401.1   1597 2681
Gen_3991403.1   1175 2217
Gen_3991951.1   1897 2907
Gen_8877722.9   7777 8888

一个awk解决方案:

$ awk '
# process first file ...
FNR==NR { # use gene seq name as index; store start value
          start[$2]=$3
          next }

# process second file ...
{ # if we have a start value for the current gene seq name ($1)
  if ( start[$1] != "" ) 
       # then print
       print "[1] " $1 "\t" "[2] " $1 "\t" "[3] " start[$1] "\t" "[4] " $2 "\t" "[5] "$3 
}
' gene.1 gene.2

[1] Gen_3989161.1       [2] Gen_3989161.1       [3] 696 [4] 1696        [5] 2720
[1] Gen_3989469.1       [2] Gen_3989469.1       [3] 693 [4] 1693        [5] 2733
[1] Gen_3989837.1       [2] Gen_3989837.1       [3] 462 [4] 1462        [5] 2515
[1] Gen_3990203.1       [2] Gen_3990203.1       [3] 27  [4] 127 [5] 2112
[1] Gen_3990467.1       [2] Gen_3990467.1       [3] 476 [4] 1476        [5] 2481
[1] Gen_3991323.1       [2] Gen_3991323.1       [3] 134 [4] 1134        [5] 2152
[1] Gen_3991401.1       [2] Gen_3991401.1       [3] 597 [4] 1597        [5] 2681
[1] Gen_3991403.1       [2] Gen_3991403.1       [3] 175 [4] 1175        [5] 2217
[1] Gen_3991951.1       [2] Gen_3991951.1       [3] 897 [4] 1897        [5] 2907

如果您需要输出与固定宽度列对齐,可以通过将print替换为适当的printf格式字符串来实现...

答案 2 :(得分:0)

由于您的数据已经按键排序,因此您可以使用join加入,awk进行格式化。使用@markp的数据(因为你没有任何公共密钥)

$ join -12 -21 -o1.2,2.1,1.3,2.2,2.3 file1 file2                | 
  awk -v OFS="\t" '{for(i=1;i<=NF;i++) 
                      printf "[%d] %s", i,$i (i==NF?ORS:OFS)}'  | 
  column -ts$'\t'

[1] Gen_3989161.1  [2] Gen_3989161.1  [3] 696  [4] 1696  [5] 2720
[1] Gen_3989469.1  [2] Gen_3989469.1  [3] 693  [4] 1693  [5] 2733
[1] Gen_3989837.1  [2] Gen_3989837.1  [3] 462  [4] 1462  [5] 2515
[1] Gen_3990203.1  [2] Gen_3990203.1  [3] 27   [4] 127   [5] 2112
[1] Gen_3990467.1  [2] Gen_3990467.1  [3] 476  [4] 1476  [5] 2481
[1] Gen_3991323.1  [2] Gen_3991323.1  [3] 134  [4] 1134  [5] 2152
[1] Gen_3991401.1  [2] Gen_3991401.1  [3] 597  [4] 1597  [5] 2681
[1] Gen_3991403.1  [2] Gen_3991403.1  [3] 175  [4] 1175  [5] 2217
[1] Gen_3991951.1  [2] Gen_3991951.1  [3] 897  [4] 1897  [5] 2907

column的最终管道是用于漂亮打印。显然,重复两次键没有任何意义,因为每行必须相同。