You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何并行化awk脚本处理多文件并正确命名输出文件

并行化Beagle文件子集提取并正确命名输出文件

我在sub.yr_by_yr文件夹下有一批文本文件,原本通过for循环调用subbeagle.awk脚本,根据文件内的表头提取MajorMinor.beagle.gz的子集,并用file11=${file1%.subbeagle.txt}生成输出文件名MM.beagle.${file11}.gz。原循环可正常运行但耗时过长,需要并行化处理。文件夹内文件命名类似sp.yrseries.site1.1.subbeagle.txt。

原串行循环代码

for file1 in $(ls sub.yr_by_yr)
do 
echo -e  "Doing sub-samples \n $file1"
file11=${file1%.subbeagle.txt}
awk -f subbeagle.awk \
       ./sub.yr_by_yr/$file1 <(zcat ../MajorMinor.beagle.gz) | gzip > sub.yr_by_yr_beagle.files/MM.beagle.${file11}.gz
done

尝试并行时遇到的问题

我曾尝试以下Parallel命令,但出现bad substitution错误:

parallel "file11=${{}%.subbeagle.txt}; awk -f $SUBBEAGLEAWKSCRIPT ./sub.yr_by_yr/{} <(zcat ../MajorMinor.beagle.gz) | gzip > sub.yr_by_yr_beagle.files/MM.beagle.${file11}.gz" ::: sub.yr_by_yr/*.subbeagle.txt

后续找到测试命令可运行,但输出文件名包含.subbeagle,不符合需求:

parallel "awk -f subbeagle.awk {} <(zcat ../MajorMinor.beagle.gz) | gzip > 'sub.yr_by_yr_beagle.files/MM.beagle.{/.}_test.gz'" ::: sub.yr_by_yr/*.subbeagle.txt

解决方案

方法一:使用GNU Parallel内置替换表达式

直接利用Parallel的正则替换语法处理文件名,和原循环的变量替换逻辑完全一致:

parallel 'awk -f subbeagle.awk {} <(zcat ../MajorMinor.beagle.gz) | gzip > sub.yr_by_yr_beagle.files/MM.beagle.{= s/\.subbeagle\.txt$// =}.gz' ::: sub.yr_by_yr/*.subbeagle.txt
  • {= s/\.subbeagle\.txt$// =}:通过正则匹配移除文件名末尾的.subbeagle.txt,等价于原循环的${file1%.subbeagle.txt}。
  • 用单引号包裹命令,避免bash提前解析变量,确保替换逻辑由Parallel执行。

方法二:结合{/.}与sed处理

如果对正则替换不熟悉,可先通过{/.}获取去掉.txt后缀的文件名,再用sed移除.subbeagle部分:

parallel 'base=$(echo {/.} | sed "s/\.subbeagle//"); awk -f subbeagle.awk {} <(zcat ../MajorMinor.beagle.gz) | gzip > sub.yr_by_yr_beagle.files/MM.beagle.$base.gz' ::: sub.yr_by_yr/*.subbeagle.txt

验证效果

针对输入文件sp.yrseries.site1.1.subbeagle.txt,两种方法都会生成输出文件MM.beagle.sp.yrseries.site1.1.gz,和原串行循环的输出命名完全一致。


附相关文件内容

subbeagle.awk脚本

# 根据表头选择列的awk脚本
BEGIN  { FS=OFS="\t" }                             # 如果输入/输出字段是制表符分隔则启用
FNR==NR { headers[$1]; next }
        { sep=""
          for (i=1; i<=NF; i++) {
              if (FNR==1 && ($i in headers)) {
                 fldids[i]
              }
              if (i in fldids) {
                 printf "%s%s",sep,$i
                 sep=OFS                            # 若未在BEGIN块设置,默认OFS为空格
              }
          }
          print ""
        }

MajorMinor.beagle.gz示例内容(解压后)

marker      allele1  allele2  FINCH_WB_ID1_splitMerged  FINCH_WB_ID1_splitMerged  FINCH_WB_ID1_splitMerged  FINCH_WB_ID2_splitMerged  FINCH_WB_ID2_splitMerged
chr1_34273  G        C        0.79924                   0.20076                   3.18183e-09               0.940649                      0.0593509
chr1_34285  G        A        0.79924                   0.20076                   3.18183e-09               0.969347                      0.0306534
chr1_34291  G        C        0.666111                  0.333847                  4.20288e-05               0.969347                      0.0306534
chr1_34299  C        G        0.000251063               0.999498                  0.000251063               0.996035                      0.00396529

内容的提问来源于stack exchange,提问作者M. Beausoleil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:45:35