我有多个文件扩展名为.profile的6列。每个文件的前3列相同。我想让输出文件包含前3个(相似)列,然后从每个文件附加第六列。附加到输出文件的列的名称应与输入文件的名称相同。输入文件如下:
FID IID PHENO CNT CNT2 SCORE
00010 0001002 2 12 2 -0.00285
00017 0001702 2 12 2 -0.00285
另一个输入文件看起来像这样
FID IID PHENO CNT CNT2 SCORE
00010 0001002 2 28 9 -0.00843036
00017 0001702 2 28 9 0.00710286
这两个文件的名称分别是“ Artery_Aorta.ENSG00000000460.12.wgt.RDat.txt.profile”和“ Artery_Aorta.ENSG00000000971.11.wgt.RDat.txt.profile”。我希望我的输出文件看起来像
FID IID PHENO ENSG00000000460.12 ENSG00000000971.11
00010 0001002 2 -0.00285 -0.00843036
00017 0001702 2 -0.00285 0.00710286
到目前为止,我已经尝试过
paste *.profile | awk '{print $1, $2, $3, $6, $6 + 6}'
但是输出不是期望的。它会将$ 6中的值加6。但是,我想在输出文件中打印每第六列并附加前几列。输出文件如下所示
FID IID PHENO SCORE 6
00010 0001002 2 -0.00843036 5.99157
00017 0001702 2 0.00710286 6.0071
有人可以帮我吗?
答案 0 :(得分:1)
AWK解决方案,如果您需要在每个输入文件中添加第六列并按输入进行排序:
awk '
(NR==FNR) { arro[++order]=$1 FS $2 FS $3; arr[$1 FS $2 FS $3]=$6; }
(NR!=FNR) { arr[$1 FS $2 FS $3]=arr[$1 FS $2 FS $3] FS $6; }
END { for (i=1;i<=order;i++) print(arro[i] FS arr[arro[i]]); }
' *.profile
输出:
FID IID PHENO SCORE SCORE
00010 0001002 2 -0.00285 -0.00843036
00017 0001702 2 -0.00285 0.00710286
输入:
$ ls *.profile
Artery_Aorta.ENSG00000000460.12.wgt.RDat.txt.profile Artery_Aorta.ENSG00000000971.11.wgt.RDat.txt.profile
这里的每个评论请求都是将添加的列替换为文件名子字符串的解决方案:
awk '
(FNR==1) {match(FILENAME,/ENSG[0-9]+\.[0-9]+/); $6=substr(FILENAME,RSTART,RLENGTH);}
(NR==FNR) { arro[++order]=$1 FS $2 FS $3; arr[$1 FS $2 FS $3]=$6; }
(NR!=FNR) { arr[$1 FS $2 FS $3]=arr[$1 FS $2 FS $3] FS $6; }
END { for (i=1;i<=order;i++) print(arro[i] FS arr[arro[i]]); }
' *.profile
输出:
FID IID PHENO ENSG00000000460.12 ENSG00000000971.11
00010 0001002 2 -0.00285 -0.00843036
00017 0001702 2 -0.00285 0.00710286
答案 1 :(得分:1)
假设输入文件用制表符分隔,并且第一列前面没有这些前导空格,则以下脚本将生成预期的输出:
#! /bin/bash
merge() {
cols=$(seq -s, 6 6 $(("$#" * 6)))
header=$(grep -o 'ENSG[0-9]*.[0-9]*' <<< "$*" | paste -s)
paste "$@" | cut -f1-3,"$cols" | sed "1s/SCORE.*/$header/"
}
merge Artery_Aorta.*