我正在尝试通过一列部分重叠的标识符(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 gene1 gene1 4.2 0.001
c1 300 400 gene4 gene4 1.05 0.5
c13 600 700 gene2 NA 1 1
我认为一种方法可以是建立一个awk
条件构造。如果您能指出正确的方向,那就太好了。
答案 0 :(得分:1)
使用https://docs.google.com/document/d/abc_xyz/preview
,请尝试以下操作:
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
AWK“FNR == NR {A [$ 1] = $ 1; b [$ 1] = $ 2; c [$ 1] = $ 3;下一个} {如果{A [$ 4] = “N / A”(一个[$ 4]!); b [$ 4] = 1; c [$ 4] = 1} printf的 “%S%S%S%S \ n”,$ 0,则[$ 4],B [$ 4],C [$ 4]} “file2的文件1
[说明]
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
是读取所述参数列表中的第一文件(在这种情况下,“文件2”)仅当要执行的命令的习惯用法。然后它会在“文件2”的地图(又名关联数组),以准值以FNR==NR { command; next}
为:
genes
不必对“ file2”进行排序。
以下各行仅读取第二文件(“文件1”)时,因为读取第一文件时,由于gene1 => gene1 (with array a)
gene1 => 4.2 (with array b)
gene1 => 0.001 (with array c)
gene4 => gene4 (with array a)
gene4 => 1.05 (with array b)
gene4 => 0.5 (with array c)
语句这些行被跳过执行。
当未定义关联数组next
(意味着在{file2“中找不到{if (!a[$4]) ..
时),行a[gene]
是将变量分配给默认值的后备选项。
在最终行打印 “文件1” 经由gene
。
答案 1 :(得分:1)
您可以使用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-
-e NA
-用NA
-o ...
—输出格式(使用<file>.<field>
指定字段)
-a 1
-保留左侧文件中的每一行
-1 5
,-2 1
-用于联接文件的字段
file1
,file2
-文件
nl -w1 -s ' ' file1
-带编号行的file1
<(sort -k X fileN)
-准备将文件N加入X列
s/NA\sNA$/1 1/
—用NA NA
1 1
| sort -n | cut -d ' ' -f 2-
-按数字排序并删除第一列
上面的示例在输出中使用空格。要使用标签,请附加| tr ' ' '\t'
:
join -e NA -o '1.1 1.2 1.3 1.4 2.1 2.2 2.3' -a 1 -1 4 -2 1 file1 file2 | sed 's/NA\sNA$/1 1/' | tr ' ' '\t'
答案 2 :(得分:0)
虚线以TAB作为最后一个字符。使用
修复此问题paste file1 file2 | sed 's/\t$/\tNA\t1\t1/g'