高效替换VCF文件染色体名

一.样品名替换

bcftools reheader -s    rename_samples.txt         input.vcf > output.vcf
# id文件,一列旧id,一列新id

二.染色体名替换

2.1 头文件+数据列(优先这个)

sh /share/nas1/yuj/script/ddradANDreseqANDgenome/vcf_tools/remap_chr.sh  all.daerwen.chr-rename.sample-rename.vcf   chromosome_mapping.txt  all.rename.daerwen.chr-rename.sample-rename.vcf

2.2 仅替换数据列

2.2.1 awk(快一点)(满足一二列要求即可替换)

## 1
awk 'BEGIN { while (getline < "map.txt") map[$1]=$2 } 
     /^##contig=<ID=/ { 
         if (match($0, /ID=[^,]+/)) { 
             id = substr($0, RSTART+3, RLENGTH-3); 
             if (id in map) sub(/ID=[^,]+/, "ID=" map[id]) 
         } print; next 
     } 
     /^#/ { print; next } 
     $1 in map { $1 = map[$1] } 1' input.vcf > output.vcf

解释:
1. **读取映射文件**:`BEGIN`块将`map.txt`读入内存,构建哈希表`map`(旧名称为键,新名称为值)。
2. **处理头信息**:
   - 对`##contig=<ID=...>`格式的行,提取旧ID并替换为新ID(如果存在映射)。
3. **跳过注释行**:其他以`#`开头的行(如`#CHROM`)直接打印。
4. **替换数据行**:对非注释行,若第1列(染色体名)在映射表中存在,则替换为新名称。

## 2  输入文件以空格分隔时,去掉下面FS字段(优先用这个)
awk 'BEGIN {
    # 设置输入和输出字段分隔符为制表符
    FS = "\t"
    OFS = "\t"
    # 加载映射关系到数组
    while (getline < "chromosome_mapping.txt") {
        map[$1] = $2
    }
}
{
    # 处理 VCF 文件
    if ($0 ~ /^#/) {
        # 保留注释行(直接打印原内容)
        print $0
    } else {
        # 替换染色体名称
        if ($1 in map) {
            $1 = map[$1]
        }
        # 使用OFS(制表符)输出各字段
        print
    }
}' input.vcf > output_renamed.vcf

awk 'BEGIN { FS="\t"; OFS="\t"; while (getline < "chromosome_mapping.txt") map[$1]=$2 } { if ($0 ~ /^#/) print $0; else { if ($1 in map) $1=map[$1]; print } }' input.vcf > output_renamed.vcf

**关键修改说明:**
1. **设置分隔符**:在`BEGIN`块中设置`FS`(输入字段分隔符)和`OFS`(输出字段分隔符)为制表符`\t`,确保输入正确解析且输出以制表符分隔。
2. **保留注释行原样**:注释行直接使用`print $0`输出原始内容,避免因字段操作导致格式变化。
3. **替换后自动制表符分隔**:非注释行替换染色体名称后,使用`print`(默认输出`$0`,各字段由`OFS`分隔)确保制表符分隔。

2.2.2 bcftools(推荐)(只适用于vcf文件)

# 1. 将映射文件转换为 bcftools 接受的格式(旧ID->新ID)
awk '{print $1 "\t" $2}' chromosome_mapping.txt > chrom_map.txt

# 2. 使用 bcftools 重命名染色体
bcftools annotate --rename-chrs chrom_map.txt input.vcf -o output_renamed.vcf