Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何合并两个选项卡分隔的文件并预定义缺少值的格式?_Bash - Fatal编程技术网

Bash 如何合并两个选项卡分隔的文件并预定义缺少值的格式?

Bash 如何合并两个选项卡分隔的文件并预定义缺少值的格式?,bash,Bash,我试图通过一列部分重叠的标识符(gene#)合并两个未排序的制表符分隔的文件,并选择预定义缺少的值并保持第一个表的顺序 在我的两个示例表上使用paste时,缺少的值最终会变成空白 cat file1 c3 100 300 gene4 c1 300 400 gene1 c13 600 700 gene2 cat file2 gene1 4.2 0.001 gene4 1.05 0.5 paste file1 file2 c3 100 300 gene1 gene1

我试图通过一列部分重叠的标识符(gene#)合并两个未排序的制表符分隔的文件,并选择预定义缺少的值并保持第一个表的顺序

在我的两个示例表上使用
paste
时,缺少的值最终会变成空白

cat file1
c3  100 300 gene4
c1  300 400 gene1
c13 600 700 gene2

cat file2
gene1   4.2 0.001
gene4   1.05    0.5

paste file1 file2
c3  100 300 gene1   gene1   4.2 0.001
c1  300 400 gene4   gene4   1.05    0.5
c13 600 700 gene2
正如您所看到的,结果毫不奇怪地显示非匹配行中的空格。有没有办法保持file1的顺序并像第三行那样填充行,如下所示:

c3  100 300 gene4   gene4   1.05 0.5
c1  300 400 gene1   gene1   4.2    0.001
c13 600 700 gene2   NA   1    1

我假设一种方法是构建一个
awk
条件构造。如果您能为我指出正确的方向,那就太好了。

使用
awk
请尝试以下方法:

awk 'FNR==NR {a[$1]=$1; b[$1]=$2; c[$1]=$3; next}
    {if (!a[$4]) {a[$4]="N/A"; b[$4]=1; c[$4]=1}
     printf "%s  %s  %s  %s\n", $0, a[$4], b[$4], c[$4]}
' file2 file1
这将产生:

c3  100 300 gene1  gene1  4.2  0.001
c1  300 400 gene4  gene4  1.05  0.5
c13 600 700 gene2  N/A  1  1
awk'FNR==NR{a[$1]=1;b[$1]=2;c[$1]=3;next} {如果(!a[$4]){a[$4]=“N/a”;b[$4]=1;c[$4]=1} printf“%s%s%s%s\n”,$0,a[$4],b[$4],c[$4]} '文件2文件1

[解释]

  • 在第1行中,
    FNR==NR{command;next}
    是一种仅在读取参数列表中的第一个文件时执行命令的习惯用法(在本例中为“file2”)。然后它创建映射(又称关联数组),将“file2”中的值关联到
    基因
作为:

  • 没有必要对“file2”进行排序

  • 以下行仅在读取第二个文件(“文件1”)时执行,因为由于
    next
    语句,在读取第一个文件时跳过了这些行

  • 当关联数组
    a[gene]
    未定义时,
    {if(!a[$4])…
    行是将变量分配给默认值的回退(这意味着在“file2”中找不到
    基因)

  • 最后一行通过
    基因
    打印“file1”的内容,后跟相关值


    • 使用
      awk
      请尝试以下操作:

      awk 'FNR==NR {a[$1]=$1; b[$1]=$2; c[$1]=$3; next}
          {if (!a[$4]) {a[$4]="N/A"; b[$4]=1; c[$4]=1}
           printf "%s  %s  %s  %s\n", $0, a[$4], b[$4], c[$4]}
      ' file2 file1
      
      这将产生:

      c3  100 300 gene1  gene1  4.2  0.001
      c1  300 400 gene4  gene4  1.05  0.5
      c13 600 700 gene2  N/A  1  1
      
      awk'FNR==NR{a[$1]=1;b[$1]=2;c[$1]=3;next} {如果(!a[$4]){a[$4]=“N/a”;b[$4]=1;c[$4]=1} printf“%s%s%s%s\n”,$0,a[$4],b[$4],c[$4]} '文件2文件1

      [解释]

      • 在第1行中,
        FNR==NR{command;next}
        是一种习惯用法,用于仅在读取参数列表中的第一个文件时执行命令(在本例中为“file2”)。然后创建映射(也称为关联数组),将“file2”中的值与
        基因关联
      作为:

      • 没有必要对“file2”进行排序

      • 以下行仅在读取第二个文件(“文件1”)时执行,因为由于
        next
        语句,在读取第一个文件时跳过了这些行

      • 当关联数组
        a[gene]
        未定义时,
        {if(!a[$4])…
        行是将变量分配给默认值的回退(这意味着在“file2”中找不到
        基因)

      • 最后一行通过
        基因
        打印“file1”的内容,后跟相关值


        • 您可以使用
          加入

          join -e NA -o '1.1 1.2 1.3 1.4 1.5 2.1 2.2 2.3' -a 1 -1 5 -2 1 <(nl -w1 -s ' ' file1 | sort -k 5) <(sort -k 1 file2) | sed 's/NA\sNA$/1 1/' | sort -n | cut -d ' ' -f 2-
          

          您可以使用
          join

          join -e NA -o '1.1 1.2 1.3 1.4 1.5 2.1 2.2 2.3' -a 1 -1 5 -2 1 <(nl -w1 -s ' ' file1 | sort -k 5) <(sort -k 1 file2) | sed 's/NA\sNA$/1 1/' | sort -n | cut -d ' ' -f 2-
          

          虚线的最后一个字符是制表符。请使用

          paste file1 file2 | sed 's/\t$/\tNA\t1\t1/g'
          

          虚线的最后一个字符是制表符。请使用

          paste file1 file2 | sed 's/\t$/\tNA\t1\t1/g'
          


          gene1
          应该连接到
          gene1
          吗?或者您只是试图将
          na11
          附加到
          file2
          中,直到它的行数与
          file1
          相同?要使用
          join
          必须对文件进行排序。是的,应该使用gene列进行连接。理想情况下,
          file1
          应该逐行进行连接d检查
          file2
          中任何一行中是否有匹配的基因条目。如果发现某些内容,则应附加file2的两个额外列,如果未发现任何内容,则应附加
          NA 1 1
          。谢谢。我们可以对其进行排序吗?初始顺序重要吗?
          gene1
          是否唯一(没有两行
          gene1
          行?)?您可以使用
          排序
          连接
          -e“NA 1 1”
          我们可以对其进行排序,如果这有帮助,我们可以在之后使用
          文件1
          将其排序到原始顺序(第一列:
          c3、c1、c13
          )作为某种排序键?基因绝对是唯一的。
          gene1
          是否应该连接到
          gene1
          ,或者您只是试图将
          NA 1 1
          附加到
          file2
          ,直到它与
          file1
          具有相同的行数?要使用
          join
          ,必须对文件进行排序。是的,应该使用gene列d连接。理想情况下,应逐行检查
          file1
          文件2
          中任何一行中是否有匹配的基因条目。如果发现了某些内容,则应追加file2的两列,如果未发现任何内容,则应追加
          NA 1
          。谢谢。我们可以对其排序吗?初始顺序重要吗?
          gene1
          唯一(没有两行
          gene1
          行?)?您可以使用
          sort
          join
          -e“NA 1 1 1”
          对其进行排序,如果这有帮助,我们可以对其进行排序,当然我们可以使用
          file1
          将其排序到原始顺序(第一列:
          c3、c1、c13
          )作为某种排序键?基因绝对是独一无二的。谢谢你的回答和解释。在我的示例代码中,它是有效的,但是当我用我的分析案例尝试它时,我得到以下错误消息:
          join:file 1未按排序顺序
          join:file 2未按排序顺序
          知道问题是什么吗通过改变基因列的顺序来调整上面的例子,现在生成了一个类似的错误
          join:file 1没有按排序顺序
          @gdeniz我想这是可以解决的,无需对
          file1
          进行排序,因为在我的现实世界中
          file1
          是生成特定数据的聚类程序的结果ta依赖顺序?@gdeniz最后一次排序将恢复顺序。谢谢你的帮助