<p>You could simply use <a href="http://www.htslib.org/doc/bcftools.html#sort" rel="noreferrer">bcftools sort</a> for it:</p>

<pre><code>$ bcftools sort input.vcf &gt; output.vcf
</code></pre>

<p>If you really want to use bash only, you can do this:</p>

<pre><code><span class="math-container">$ grep "^#" input.vcf &gt; output.vcf
$</span> grep -v "^#" input.vcf| sort -k1,1V -k2,2g &gt;&gt; output.vcf
</code></pre>

<p>The first command will write the header information to the new vcf file.
The second will sort by contig name and position and append the result to the new vcf file.</p>

<p>fin swimmer</p>

CC BY-SA 4.0
2019-01-16T17:53:09.577Z
I get this: Writing to /tmp/bcftools-sort.7BfymN
[W::vcf_parse] Contig 'Erumb1_s00000030' is not defined in the header. (Quick workaround: index the file with tabix.).  So, this is where I started, having to index the .vcf.  Looks like the grep approach worked, but I've got to give it a closer look.
Peter Pearman
CC BY-SA 4.0
2019-01-16T18:25:10.950Z
@PeterPearman first check that your `sort` implementation deals with the `-k` flag correctly. The command in this answer should work fine for GNU `sort` (the default on Linux) but I'm not sure it works correctly with BSD `sort` (default on macOS). The [man page](https://ss64.com/osx/sort.html) I found seems to suggest that the `V` and `g` modifiers aren't supported. However, you don't really need the `V` and you can use `n` instead of `g`: `sort -k1,1 -k2,2n`.
terdon
CC BY-SA 4.0
2019-01-16T19:23:17.713Z
`bcftools` is very strict about the correct `vcf` structure. It heavily relies on the header data. This should include contig information and any key used in the `INFO` and `FORMAT`column. You should always have this information there. `bcftools` is a very powerful tool. So be strict to your `vcf` file, that you can use it.
finswimmer
CC BY-SA 4.0
2019-01-16T19:25:58.090Z
@terdon is right. `V` isn't needed. I'm used to it, handling human chromosome names. Doing it that way `chr2` is located before `chr10`. But in `vcf` file the only conditions are, that the contig names build blocks and inside this blocks the position is ascending.
finswimmer
CC BY-SA 4.0
2019-01-16T17:45:39.340Z
2019-01-16T17:45:39.340Z
finswimmer
<p>Use a subshell. First print the header and then the variant lines, sorting by chromosome and position:</p>

<pre><code>(grep ^"#" input.vcf; grep -v ^"#" input.vcf | sort -k1,1 -k2,2n) &gt; sorted.vcf
</code></pre>

CC BY-SA 4.0
2019-05-08T08:03:33.990Z
2019-05-08T08:40:48.460Z
2019-05-08T08:40:48.460Z
atongsa
<p>Due to tabix constraints, I need to sort a vcf so that contigs and then positions within contigs occur in numerical order in the vcf.  I don't know if the following will sort positions within contigs, but I tried this:</p>

<pre><code>cat in.vcf | vcf-sort -c &gt; out.vcf
</code></pre>

<p>but was informed:</p>

<pre><code>Old version of sort command installed, please run without the -c option.
</code></pre>

<p>I've read that can cause problems <a href="http://bo-peng.blogspot.com/2011/05/upgrading-sorting-and-merging-next-gen.html" rel="noreferrer">here</a>. Further, my contigs are't numeric, but are something like this: 'Erumb1_s00000030'. </p>

<p>I see two possible solutions.  (1) I am on Mac OS Mojave, and if there were a way to install the a new unix-style sort, I could use it. I tried homebrew and didn't find anything. (2) there are likely some bash commands that would do it.  If anyone has an idea in either of these directions, I would appreciate it. </p>

CC BY-SA 4.0
2019-01-16T19:25:46.720Z
It might be worth posting a question about these tabix constraints. We could be able to help you fix that which would allow you to use bcftools.
terdon
<vcf><bash><vcftools>
Sort vcf by contig and position within contig
# Sort vcf by contig and position within contig

(Asked by: username_0 on 2019-01-16)

Due to tabix constraints, I need to sort a vcf so that contigs and then positions within contigs occur in numerical order in the vcf.  I don't know if the following will sort positions within contigs, but I tried this:
cat in.vcf | vcf-sort -c > out.vcf

but was informed:
Old version of sort command installed, please run without the -c option.

I've read that can cause problems here. Further, my contigs are't numeric, but are something like this: 'Erumb1_s00000030'. 
I see two possible solutions.  (1) I am on Mac OS Mojave, and if there were a way to install the a new unix-style sort, I could use it. I tried homebrew and didn't find anything. (2) there are likely some bash commands that would do it.  If anyone has an idea in either of these directions, I would appreciate it.

**Tags:** vcf, bash, vcftools
> **Comments:**
> **username_1**: It might be worth posting a question about these tabix constraints. We could be able to help you fix that which would allow you to use bcftools.  

---

## 2 answers

### Answer by username_2 on 2019-01-16. Score: 6 | Accepted answer

You could simply use bcftools sort for it:
$ bcftools sort input.vcf > output.vcf

If you really want to use bash only, you can do this:
$ grep "^#" input.vcf > output.vcf
$ grep -v "^#" input.vcf| sort -k1,1V -k2,2g >> output.vcf

The first command will write the header information to the new vcf file.
The second will sort by contig name and position and append the result to the new vcf file.
fin swimmer

> **Comments:**
> **username_0**: I get this: Writing to /tmp/bcftools-sort.7BfymN [W::vcf_parse] Contig 'Erumb1_s00000030' is not defined in the header. (Quick workaround: index the file with tabix.).  So, this is where I started, having to index the .vcf.  Looks like the grep approach worked, but I've got to give it a closer look.  
> **username_1**: @PeterPearman first check that your `sort` implementation deals with the `-k` flag correctly. The command in this answer should work fine for GNU `sort` (the default on Linux) but I'm not sure it works correctly with BSD `sort` (default on macOS). The [man page](https://ss64.com/osx/sort.html) I found seems to suggest that the `V` and `g` modifiers aren't supported. However, you don't really need the `V` and you can use `n` instead of `g`: `sort -k1,1 -k2,2n`.  
> **username_2**: `bcftools` is very strict about the correct `vcf` structure. It heavily relies on the header data. This should include contig information and any key used in the `INFO` and `FORMAT`column. You should always have this information there. `bcftools` is a very powerful tool. So be strict to your `vcf` file, that you can use it.  
> **username_2**: @terdon is right. `V` isn't needed. I'm used to it, handling human chromosome names. Doing it that way `chr2` is located before `chr10`. But in `vcf` file the only conditions are, that the contig names build blocks and inside this blocks the position is ascending.  

---

### Answer by username_3 on 2019-05-08. Score: 2

Use a subshell. First print the header and then the variant lines, sorting by chromosome and position:
(grep ^"#" input.vcf; grep -v ^"#" input.vcf | sort -k1,1 -k2,2n) > sorted.vcf


---

