首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环内循环vcftools bash

循环内循环vcftools bash
EN

Stack Overflow用户
提问于 2020-12-31 20:56:47
回答 1查看 92关注 0票数 2

我正在尝试使用vcftools包来计算weir和cockerham的fst。我想在第一个例子中循环两对种群,然后在1000基因组项目的所有变体上循环这些种群:每个染色体包含一个单独的vcf文件。例如,对于pop1和pop2,对于pop3和pop4,计算染色体1-10的fst。每个人口文件(例如,LWKfile )都包含属于此人口的个人的列表。

我尝试过:

代码语言:javascript
复制
for population in LWK_GBR YRI_FIN; do

firstpop=$(echo $population | cut -d '_' -f1)
secondpop=$(echo $population | cut -d '_' -f2)

for filename in *.vcf.gz; do

vcftools --gzvcf ${filename} \
--weir-fst-pop /outdir/${firstpop}file \
--weir-fst-pop /outdir/${secondpop}file \
--out /out/${population}_${filename}

done

done  

然而,这并不是循环遍历所有的文件,并且似乎卡在10号染色体上。有没有更有效的方法在bash中执行这一点,因为我担心循环中的循环会太慢。

EN

回答 1

Stack Overflow用户

发布于 2020-12-31 21:26:28

然而,这并没有循环遍历所有的文件,并且似乎卡在了10号染色体上。我担心循环中的循环会太慢。

你确定是for filename in *.vcf.gz太慢而无法遍历所有文件吗?

尝试将echo放在vcftools之前,看看它是否仍然卡住。

为了能够做出正确的选择,你需要确定什么需要花费太多的时间。

例如,如果它是vcftools,那么您可能不需要等待此命令结束,并考虑进行一些异步处理。

如果一个循环的文件太多,您还应该考虑进行一些并行处理。

此外,您似乎对所有.vcf.gz文件重复了两次循环。它可能会更快地逆转你的两个循环。

以下是使用bash进行并行和异步处理的示例

代码语言:javascript
复制
#!/bin/bash

MAX_PARALLEL_PIDS=4 # adjust regarding your own machin capacity (cpu available, etc... it could be dynamically calculated)

declare -a POPS
declare -a PIDS

POPS=("LWK_GBR" "YRI_FIN")

# your heavy treatment in a function
process() {
  pop="${1}"
  filename="${2}"
  firstpop="${pop%%_*}" # no need to call an external program here
  secondpop="${pop#*_}" # same here

  vcftools --gzvcf "${filename}" \
     --weir-fst-pop "/outdir/${firstpop}file" \
     --weir-fst-pop "/outdir/${secondpop}file" \
     --out "/out/${pop}_${filename}"
}

# a function which is usefull to wait all process when your "thread pool" reached its limits
wait_for_pids() {
  for pid in "${PIDS[@]}"; do
    [[ $pid =~ ^[0-9]+ ]] && wait $pid
  done
  unset PIDS
}

i=0
for filename in *.vcf.gz; do
 if [[ $i -ge $MAX_PARALLEL_PIDS ]]; then
   i=0
   wait_for_pids
 fi

 for population in "${POPS[@]}"; do
   process "${population}" "${filename}" & # You won't wait for the end here
   PIDS[$i]=$!
   (( i++ ))
 done
done

# at the end wait for the remaining processes
wait_for_pids

注意:把[[条件中的变量放在一边,你应该注意引用可以包含一些空格的变量,特别是文件名。否则它会坏掉的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65521198

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档