我想合并2个文件并将其分配到新文件,同时在unix中使用优选的awk添加新的不存在的列:
文件1:VDR.txt没有标题,空格分隔,如下所示:
chr12-45000000-50000000 --- rs192072617 48225416 0.000 0.270 0.999 0 -1 -1 -1
chr12-45000000-50000000 --- rs181728325 48225429 0.000 0.144 1.000 0 -1 -1 -1
chr12-45000000-50000000 --- rs187216594 48225500 0.000 0.007 1.000 0 -1 -1 -1
文件2:METAL1.tbl有一个标题,标签分隔,如下所示:
MarkerName Allele1 Allele2 Weight Zscore P-value Direction HetISq HetChiSq HetDf HetPVal
rs192072617 a g 2887.00 1.579 0.1143 ++ 0.0 0.032 1 0.8579
rs7929618 c g 2887.00 -1.416 0.1568 -+ 47.4 1.899 1 0.1681
rs181728325 t c 2887.00 1.469 0.1419 ++ 73.9 3.830 1 0.05033
rs7190157 a c 2887.00 1.952 0.05088 +- 72.7 3.669 1 0.05542
rs12364336 a g 2887.00 -1.503 0.1328 -+ 69.8 3.306 1 0.06902
rs187216594 t c 2887.00 -0.082 0.9349 +- 74.8 3.964 1 0.04649
rs12562373 a g 2887.00 -0.290 0.7717 -+ 0.0 0.150 1 0.6984
文件的行数不等,第一个文件(VDR.txt)比第二个文件(METAL1.tbl)短得多。
我想:
"-"
之前的字符从第一个文件的第一列(VDR.txt)所以我希望在最后有一个输出文件(output.txt):
gene MarkerName chr BP impute Allele1 Allele2 Weight Zscore P-value Direction HetISq HetChiSq HetDf HetPVal
VDR rs192072617 chr12 48225416 --- a g 2887 1.579 0.1143 ++ 0 0.032 1 0.8579
VDR rs181728325 chr12 48225429 --- t c 2887 1.469 0.1419 ++ 73.9 3.83 1 0.05033
VDR rs187216594 chr12 48225500 --- t c 2887 -0.082 0.9349 +- 74.8 3.964 1 0.04649
我的尝试:
$ awk 'FNR==NR {a[$1]=$1" "$2" "$3" "$4" "$5;next}{print $3, gensub(/-.*/, "", $1), $4, $2, a[$3]}' METAL1.tbl VDR.txt
它确实以正确的方式获取chr列和列顺序,但不幸的是只打印了VDR.txt中的所需列而不是合并文件。
我知道这是一个相当复杂的例子,任何帮助或建议都会非常感激。
谢谢,
梅尔
答案 0 :(得分:3)
只要不需要标题行,就可以直接使用一个相当简单的awk
脚本:
$ awk 'FNR == NR { sub(/-.*/, "", $1); row[$3] = "VDR " $3 " " $1 " " $4 " " $2 }
> FNR != NR { if ($1 in row) { name = $1; $1 = ""; print row[name] $0 } }' \
> VDR.txt METAL1.tbl
VDR rs192072617 chr12 48225416 --- a g 2887.00 1.579 0.1143 ++ 0.0 0.032 1 0.8579
VDR rs181728325 chr12 48225429 --- t c 2887.00 1.469 0.1419 ++ 73.9 3.830 1 0.05033
VDR rs187216594 chr12 48225500 --- t c 2887.00 -0.082 0.9349 +- 74.8 3.964 1 0.04649
$
必须按照显示的顺序列出文件才能使用。
FNR == NR
行处理第一个文件。 sub
在第一个字段中删除了第一个短划线及其后面的所有内容;赋值由$3
中的标记名键控,并包含行开头的信息 - 固定代码,标记名称,缩小的染色体编号,BP和标记为'的破折号组。 &插补39#;
FNR != NR
行处理其他文件。当第1列中的值与row
数组中的键匹配时,则从当前行中删除键(在$0
的开头留下原位),然后打印row
与$0
联系在一起。
没有必要特别对待标题线;值MarkerName
不匹配第一个文件中的任何实际标记名称,因此该行只是被忽略。
答案 1 :(得分:2)
$ cat > test.awk
NR==FNR {
sub(/-.*/,"",$1) # remove from 1st dash forward
a[$3]="VDR" OFS $3 OFS $1 OFS $4 OFS $2 # cols 1-4 of the 1st file
next
}
FNR==1 {
printf "%s", "H0" OFS "H3" OFS "H1" OFS "H4" OFS "H2" # 1st part of header
}
FNR==1 || $1 in a { # header and matching rows
print a[$1], $0 # print'em
}
$ awk -f test.awk VDR.txt METAL1.tbl
H0 H3 H1 H4 H2 MarkerName Allele1 Allele2 Weight Zscore P-value Direction HetISq HetChiSq HetDf HetPVal
VDR rs192072617 chr12 48225416 --- rs192072617 a g2887.00 1.579 0.1143 ++ 0.0 0.032 1 0.8579
VDR rs181728325 chr12 48225429 --- rs181728325 t c2887.00 1.469 0.1419 ++ 73.9 3.830 1 0.05033
VDR rs187216594 chr12 48225500 --- rs187216594 t c2887.00 -0.082 0.9349 +- 74.8 3.964 1 0.04649
作为一个单行:
awk 'NR==FNR { sub(/-.*/,"",$1); a[$3]="VDR" OFS $3 OFS $1 OFS $4 OFS $2; next} FNR==1 {printf "%s", "H0" OFS "H3" OFS "H1" OFS "H4" OFS "H2"} FNR==1 || $1 in a {print a[$1], $0}' VDR.txt METAL1.tbl
答案 2 :(得分:1)
我已经对两个数据文件进行了排序以使用join
命令 - 这会影响输出中的行顺序 - 如果不希望我可以使用其他方法
export LANG=C
genef=$1
metalf=$2
gene=$(basename $genef .txt)
join -13 -21 <(sort -k3,3 $genef) <(sort -k1,1 $metalf)|
awk -vgene=$gene '
{
marker=$1
chr=substr($2, 1, index($2, "-")-1)
bp=$4
impute=$3
printf("%s\t%s\t%s\t%s\t%s", gene, marker, chr, bp, impute)
for(i=12; i<=NF; ++i)
printf("\t%s", $i)
printf("\n")
}
'
这是制表符分隔的输出
VDR rs181728325 chr12 48225429 --- t c 2887.00 1.469 0.1419 ++ 73.9 3.830 1 0.05033
VDR rs187216594 chr12 48225500 --- t c 2887.00 -0.082 0.9349 +- 74.8 3.964 1 0.04649
VDR rs192072617 chr12 48225416 --- a g 2887.00 1.579 0.1143 ++ 0.0 0.032 1 0.8579