In addition to the answer from @gringer there is a bcftools
plugin called split
that can do this, but gives you the added ability to output single-sample VCFs by specifying a filename for each sample.
$ bcftools +split
About: Split VCF by sample, creating single-sample VCFs.
Usage: bcftools +split [Options]
Plugin options:
-e, --exclude EXPR exclude sites for which the expression is true (applied on the outputs)
-i, --include EXPR include only sites for which the expression is true (applied on the outputs)
-k, --keep-tags LIST list of tags to keep. By default all tags are preserved
-o, --output DIR write output to the directory DIR
-O, --output-type b|u|z|v b: compressed BCF, u: uncompressed BCF, z: compressed VCF, v: uncompressed VCF [v]
-r, --regions REGION restrict to comma-separated list of regions
-R, --regions-file FILE restrict to regions listed in a file
-S, --samples-file FILE list of samples to keep with second (optional) column for basename of the new file
-t, --targets REGION similar to -r but streams rather than index-jumps
-T, --targets-file FILE similar to -R but streams rather than index-jumps
Examples:
# Split a VCF file
bcftools +split input.bcf -Ob -o dir
# Exclude sites with missing or hom-ref genotypes
bcftools +split input.bcf -Ob -o dir -i'GT="alt"'
# Keep all INFO tags but only GT and PL in FORMAT
bcftools +split input.bcf -Ob -o dir -k INFO,FMT/GT,PL
# Keep all FORMAT tags but drop all INFO tags
bcftools +split input.bcf -Ob -o dir -k FMT
So if you had the following samples file samples.tsv
sample1 sample1
sample2 sample2
You can run it and get the following
$ bcftools +split -S samples.tsv -o outdir in.vcf
$ ls
in.vcf sample1.vcf sample2.vcf
Without the second column, you would just get a single VCF with the two samples in it (as you would with view
)