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

如何在Bash中用for循环合并文件并提取指定列?

问题:批量合并指定文件的指定列并处理输出

需求说明

  • 合并指定路径下所有*ReadsPerGene.out.tab文件的列
  • 提取每行的第一列,以及后续每第4列(对应每个输入文件的第4列)
  • 通过tail跳过前4行、sed处理基因前缀后输出最终结果

原手动实现代码

paste 1.out.tab 2.out.tab 3.out.tab 4.out.tab \
| awk '{for(i=1;i<=NF;i+=4){printf "%s ",$i;} print ""}' | \
tail -n +5 > tmpfile
cat tmpfile | sed "s/^ENSG*//" >gene_count.txt

错误的循环尝试代码

for f in `./alignments/repaired_reads/*ReadsPerGene.out.tab | sed 's/.ReadsPerGene.out.tab//'`;
paste "$f"\.out.tab | \
awk '{for(i=1;i<=NF;i+=4){printf "%s ",$i;} print ""}' | \
tail -n +5 > tmpfile
cat tmpfile | sed "s/^ENSG*://" > gene_count.txt

样本输入

文件1:./alignments/repaired_reads/SRR9200814ReadsPerGene.out.tab

N_unmapped  18517   18517   18517
N_multimapping  1620    1620    1620
N_noFeature 8046    33145   33275
N_ambiguous 5860    1201    1034
ENSG00000160072 0   0   0
ENSG00000279928 0   0   0
ENSG00000228037 0   0   0
ENSG00000142611 0   0   0
ENSG00000284616 0   0   0
ENSG00000157911 0   0   0

文件2:./alignments/repaired_reads/SRR9200815ReadsPerGene.out.tab

N_unmapped  124416  124416  124416
N_multimapping  19165   19165   19165
N_noFeature 40924   384454  392595
N_ambiguous 99220   21834   20712
ENSG00000160072 0   0   0
ENSG00000279928 0   0   0
ENSG00000228037 0   0   0
ENSG00000142611 35  22  13
ENSG00000284616 0   0   0
ENSG00000157911 24  22  8

期望输出

N_unmapped   18517  124416
N_multimapping   1620  19165
N_noFeature     33275  392595
N_ambiguous  1034  20712
ENSG00000160072     0  0
ENSG00000279928  0  0
ENSG00000228037  0  0
ENSG00000142611  0  13
ENSG00000284616  0  0
ENSG00000157911  0  8

修正后的脚本

# 用数组存储所有目标文件路径,避免文件名含空格等特殊字符的问题
files=(./alignments/repaired_reads/*ReadsPerGene.out.tab)

# 一次性合并所有文件,提取指定列,处理后输出
paste "${files[@]}" | \
awk '{
    printf "%s", $1;  # 输出第一列(基因名/统计项)
    for(i=4; i<=NF; i+=4){  # 从第4列开始,每间隔4列取一次(对应每个文件的第4列)
        printf " %s", $i;
    }
    print "";  # 每行结束换行
}' | \
tail -n +5 | \
sed 's/^ENSG//' > gene_count.txt

错误点说明

  1. 循环逻辑错误:原代码试图通过管道切割文件名再拼接,写法完全错误,直接用通配符获取所有文件路径即可,无需额外处理文件名。
  2. paste命令误用:原循环中每次仅传入单个文件给paste,根本没实现多文件合并,正确做法是一次性将所有文件路径传给paste。
  3. sed正则错误:原代码s/^ENSG*://存在两个问题:ENSG*会匹配ENS加任意个G(不符合需求),且输入中没有冒号,应改为s/^ENSG//准确去掉基因ID开头的ENSG。

内容的提问来源于stack exchange,提问作者Anon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:23:08