如何修改VCF文件中的个体样本编码?工具或Bash实现咨询
批量修改VCF样本名(保留数字序列号)
针对你的需求,完全可以用bcftools(推荐,适合大文件)或Bash脚本实现样本名的批量重命名,以下是具体方案:
方法一:使用bcftools(高效处理大VCF文件)
bcftools是处理VCF文件的专业工具,对于包含2万+个体的大文件,速度和稳定性都更优。
步骤1:生成样本名映射文件
提取当前所有样本名:
bcftools query -l input.vcf > original_samples.txt如果是压缩的
.vcf.gz文件,直接替换为input.vcf.gz即可,bcftools会自动识别。生成新的样本名(提取数字序列号):
用sed匹配并去除冗余内容(前缀、.CEL、_vX、_RS等):sed -E 's/^.*_([0-9]+)(_v[0-9])?(_RS)?\.CEL$/\1/' original_samples.txt > new_samples.txt这个正则会:
- 匹配最后一个下划线后的数字序列
- 忽略
_v2这类版本后缀和_RS标记 - 去掉末尾的
.CEL
合并成映射文件(原样本名→新样本名):
paste original_samples.txt new_samples.txt > sample_mapping.txt
步骤2:重写VCF表头的样本名
用bcftools reheader批量替换样本名:
bcftools reheader --samples sample_mapping.txt -o output.vcf input.vcf
如果需要输出压缩文件,加上-Oz参数:
bcftools reheader --samples sample_mapping.txt -Oz -o output.vcf.gz input.vcf.gz
方法二:Bash脚本直接处理VCF文件
如果不想依赖bcftools,可以用awk+sed组合直接修改VCF的表头行:
#!/bin/bash INPUT="input.vcf" OUTPUT="output.vcf" # 处理表头行(#CHROM开头的行) head -n 1 "$INPUT" | awk -F'\t' ' BEGIN {OFS="\t"} { # 保留前9列固定字段 for (i=1; i<=9; i++) printf "%s%s", $i, OFS; # 从第10列开始处理样本名 for (i=10; i<=NF; i++) { # 去除最后一个下划线前的所有前缀 sub(/^.*_/, "", $i); # 去除版本后缀和.CEL sub(/(_v[0-9]+)?\.CEL$/, "", $i); # 去除_RS及后续内容 sub(/_RS.*$/, "", $i); # 输出处理后的样本名,最后一列加换行 printf "%s%s", $i, (i==NF ? "\n" : OFS); } }' > "$OUTPUT" # 追加剩余的基因型数据行 tail -n +2 "$INPUT" >> "$OUTPUT"
注意事项
- 测试正则有效性:先拿几个样本名测试
sed或awk的处理逻辑,确保数字序列号提取正确,比如:0_0_473294.CEL→4732940_0_347293_v2.CEL→347293abc_RS12345.CEL→12345
- 备份原文件:修改前务必备份原始VCF,避免数据丢失。
- 压缩文件适配:如果处理
.vcf.gz,Bash脚本中可以用zcat "$INPUT"代替head -n1 "$INPUT",最后用gzip "$OUTPUT"压缩结果。
内容的提问来源于stack exchange,提问作者Khaleesi95
相关产品推荐
相关产品推荐

