根据多个数组值过滤文件行
Filter rows of files conditional on multiple arrays values
我有许多文件 (N>1000),其中包含 qtl 摘要数据,例如假设第一个文件由六行组成(实际上它们都是 GWAs/imputed 具有 >10M SNP 的文件)
cat QTL.1.txt
Chr Rs BP beta se pvalue
11 rs11224233 134945522 0.150216 0.736939 0.962375
11 rs4616056 134945709 0.129518 0.371824 0.910326
11 rs11823417 134945710 0.103462 0.41737 0.845826
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
11 rs147621717 134946277 0.105365 0.196168 0.86476
我想根据染色体和基因列表的位置过滤每个数据集(我的列表有 100 个基因,但现在假设它有 2 个);因此创建 N_QTL*N_Genes 文件。我想通过每个 QTL 的每个 gene/position。基因的染色体、位置和名称存储在四个数组中,我想迭代读取这些数组并保存每个基因的每个 qtl 文件的输出。
到目前为止我所做的没有用,我知道 awk 不是最好的方法:
declare -a array1
declare -a array2
declare -a array3
declare -a array4
array1=(11 11) #chromosome
array2=(134945709 134945765) #start gene position
array3=(134946034 134946277) #end gene position
array4=(A B) # gene name
for qtl in 1; do # in reality it would be for qtl in 1 1000
for ((i=0; i<${#array1[@]}; i++)); do
cat QTL.$qtl.txt | awk '=='array1[$i]' && >='array2[$i]' &&
<='array3[$i]' {print[=11=]}' > Gene.${array4[$i]}_QTL.$qtl.txt;
done;
done
在 awk 中,$1 是染色体,$3 是位置 - 因此根据这些进行过滤。
所以我对基因 A 的 QTL.1.txt 的预期输出是
cat Gene.A_QTL.1.txt
Chr Rs BP beta se pvalue
11 rs4616056 134945709 0.129518 0.371824 0.910326
11 rs11823417 134945710 0.103462 0.41737 0.845826
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
对于 QTL。1.txt 对于基因 B 将是
cat Gene.B_QTL.1.txt
Chr Rs BP beta se pvalue
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
11 rs147621717 134946277 0.105365 0.196168 0.86476
我最终得到的是空文件,因为我要求根据数组的值过滤这些列的方式可能不起作用。
非常感谢任何帮助!
提前谢谢你
混合使用 bash 和 awk 来解析文件并不总是最好的方法。
这里是一个仅使用 awk 的解决方案。
假设您已将信息分配给文件中的 bash 数组:
$ cat info
11 134945765 154945765 Gene1
12 134945522 174945522 Gene2
您可以使用以下 awk 脚本对数据文件执行查找:
awk 'NR==FNR{
for(i=2;i<=NF;i++)
a[,i]=$i
next
}
a[,2]<= && a[,3]>={
print [=11=] > a[,4]"_QTL"
}' info QTL.1.txt
这将创建一个包含以下内容的文件:
$ cat Gene1_QTL
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
11 rs147621717 134946277 0.105365 0.196168 0.86476
可能与您看到的不完全一样,但我希望这对您有所帮助...
如果多个基因位于同一条染色体上(使用基因名而不是 chr 作为 Key),您可能需要执行以下操作:
awk 'NR==FNR{
chr[]=;
start[]=;
end[]=;
}
NR!=FNR{
for (var in chr){
name=var"_"FILENAME;
if(chr[var]== && start[var] <= && end[var]>=){
print [=10=] > name;
}
}
}' info QTL
我有许多文件 (N>1000),其中包含 qtl 摘要数据,例如假设第一个文件由六行组成(实际上它们都是 GWAs/imputed 具有 >10M SNP 的文件)
cat QTL.1.txt
Chr Rs BP beta se pvalue
11 rs11224233 134945522 0.150216 0.736939 0.962375
11 rs4616056 134945709 0.129518 0.371824 0.910326
11 rs11823417 134945710 0.103462 0.41737 0.845826
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
11 rs147621717 134946277 0.105365 0.196168 0.86476
我想根据染色体和基因列表的位置过滤每个数据集(我的列表有 100 个基因,但现在假设它有 2 个);因此创建 N_QTL*N_Genes 文件。我想通过每个 QTL 的每个 gene/position。基因的染色体、位置和名称存储在四个数组中,我想迭代读取这些数组并保存每个基因的每个 qtl 文件的输出。
到目前为止我所做的没有用,我知道 awk 不是最好的方法:
declare -a array1
declare -a array2
declare -a array3
declare -a array4
array1=(11 11) #chromosome
array2=(134945709 134945765) #start gene position
array3=(134946034 134946277) #end gene position
array4=(A B) # gene name
for qtl in 1; do # in reality it would be for qtl in 1 1000
for ((i=0; i<${#array1[@]}; i++)); do
cat QTL.$qtl.txt | awk '=='array1[$i]' && >='array2[$i]' &&
<='array3[$i]' {print[=11=]}' > Gene.${array4[$i]}_QTL.$qtl.txt;
done;
done
在 awk 中,$1 是染色体,$3 是位置 - 因此根据这些进行过滤。
所以我对基因 A 的 QTL.1.txt 的预期输出是
cat Gene.A_QTL.1.txt
Chr Rs BP beta se pvalue
11 rs4616056 134945709 0.129518 0.371824 0.910326
11 rs11823417 134945710 0.103462 0.41737 0.845826
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
对于 QTL。1.txt 对于基因 B 将是
cat Gene.B_QTL.1.txt
Chr Rs BP beta se pvalue
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
11 rs147621717 134946277 0.105365 0.196168 0.86476
我最终得到的是空文件,因为我要求根据数组的值过滤这些列的方式可能不起作用。
非常感谢任何帮助! 提前谢谢你
混合使用 bash 和 awk 来解析文件并不总是最好的方法。
这里是一个仅使用 awk 的解决方案。
假设您已将信息分配给文件中的 bash 数组:
$ cat info
11 134945765 154945765 Gene1
12 134945522 174945522 Gene2
您可以使用以下 awk 脚本对数据文件执行查找:
awk 'NR==FNR{
for(i=2;i<=NF;i++)
a[,i]=$i
next
}
a[,2]<= && a[,3]>={
print [=11=] > a[,4]"_QTL"
}' info QTL.1.txt
这将创建一个包含以下内容的文件:
$ cat Gene1_QTL
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
11 rs147621717 134946277 0.105365 0.196168 0.86476
可能与您看到的不完全一样,但我希望这对您有所帮助...
如果多个基因位于同一条染色体上(使用基因名而不是 chr 作为 Key),您可能需要执行以下操作:
awk 'NR==FNR{
chr[]=;
start[]=;
end[]=;
}
NR!=FNR{
for (var in chr){
name=var"_"FILENAME;
if(chr[var]== && start[var] <= && end[var]>=){
print [=10=] > name;
}
}
}' info QTL