Unix将字符串和数字排序在一起

时间:2013-07-06 18:04:20

标签: string unix sorting numbers

我认为应该是一个常见的问题,但我还没有找到任何好的解决方案。

我有一个文件,其中每一行都有染色体编号,染色体中的起始位置和一些相关值,如下所示。

1       1.07299851019   1       1.07299851019   HQ      chrY    2845223         +       0.251366120219  46      
1       1.06860686763   1       1.06860686763   HQ      chr10   88595309        +       0.256830601093  47      
1       1.04688316093   3       3.14064948278   HQ      chr6    49126474        +       0.295081967213  54      
1       1.1563829915    1       1.1563829915    HQ      chrX    16428176        +       0.185792349727  34      

我想在染色体(第6列)和起始位置(第7列)上使用unix sort命令对此文件进行排序。在我四处寻找之后,我想出了这个,这让我非常接近:

nohup sort -t $'\t' -k 6.4,6.5n -k 7,7n   

我无法解决的剩余问题是,编号为数字的染色体排序正确,染色体X和染色体Y在起始位置排序在一起,如下所示:

1       0.978579587641  9       8.80721628876   HQ      chrX    2861057 -       0.431693989071  79      
1       0.979500536702  1       0.979500536702  HQ      chrY    2861314 -       0.420765027322  77      
1       0.969979601694  9       8.72981641525   HQ      chrX    2861649 -       0.469945355191  86   

我知道可以解决,例如通过用数字替换chrX和chrY,或编写一个程序来解决它,但是能够使用一个简单的命令会非常好,特别是因为文件大小通常很大而且我反复这样做。

如果染色体排列顺序为1到22然后是X然后是Y,那也很好。我的命令是染色体X和Y首先出现,然后是1到22号染色体。

3 个答案:

答案 0 :(得分:2)

要将XY分开,您可以指定后备密钥:

nohup sort -t $'\t' -k 6.4,6.5n -k 6 -k 7,7n

(这表示如果在数字上比较字段6.4,6.5中的两行是等效的,那么下一步是在字段6 中对它们进行比较 - 数字,在尝试字段7之前)。

免责声明:这不符合您上一段中的目标:

  

如果染色体排列顺序为1到22然后是X然后是Y,那也很好。我的命令是染色体X和Y首先出现,然后是1到22号染色体。

因为XY在数字排序期间仍会被视为零,并且后备不会更改。希望你无论如何都觉得它很有用。

  

我知道可以解决,例如用数字代替chrX和chrY,[...]

事实上,你可以动态地进行替换:

sed 's/chrX/chr23/; s/chrY/chr24/' |
  sort -t $'\t' -k 6.4,6.5n -k 7,7n |
  sed 's/chr23/chrX/; s/chr24/chrY/'

(请注意,此命令中的换行符是可选的;为了便于阅读,我将它们包括在内,但如果您愿意,可以将它放在一行上,如果/实际使用它的话。)

答案 1 :(得分:2)

如果您的sort版本支持用于排序字母数字列的-V选项,那么您可以执行以下操作:

$ cat file
1   1.07299851019   1   1.07299851019   HQ  chrY    2845223     +   0.251366120219  46
1   1.06860686763   1   1.06860686763   HQ  chr10   88595309    +   0.256830601093  47
1   1.04688316093   3   3.14064948278   HQ  chr6    49126474    +   0.295081967213  54
1   1.1563829915    1   1.1563829915    HQ  chrX    16428176    +   0.185792349727  34

$ sort -t$'\t' -k6V -k7n file
1   1.04688316093   3   3.14064948278   HQ  chr6    49126474    +   0.295081967213  54
1   1.06860686763   1   1.06860686763   HQ  chr10   88595309    +   0.256830601093  47
1   1.1563829915    1   1.1563829915    HQ  chrX    16428176    +   0.185792349727  34
1   1.07299851019   1   1.07299851019   HQ  chrY    2845223     +   0.251366120219  46

答案 2 :(得分:0)

从以前开始详细阐述jaypal的答案...

您可以按以下方式每列更改排序条件:

sort -k1,1V input.txt

这将使用上述here引述的-V选项对第1列和第1列进行排序。

  

-V的意思是“文本内自然的(版本)数字排序”(类型   人进行排序以找出答案),然后神奇地对数字和文本进行排序。

如果在制表符分隔的文件中有多个列,并且想要指定主列的排序顺序,则可以执行以下操作:

sort -k14,14V -k1,1n input.txt

以上内容将第14列用作第一个排序索引并应用-V排序算法,然后将第1列用作第二个排序索引并使用数字排序。 (这在某些圈子中可能对按染色体然后按位置排序很有用。)

要为OSX用户解决缺少的-V选项:

  

Mac OS X本机类型不支持-V,您将拥有   安装GNU核心实用程序并改用gsort。

要快速了解-V排序的工作原理,请参见以下示例...

示例输入:

chr21   
chr2    
chr3    
chrY    
chr1    
chr3    
chr10   
chrX    

V排序的输出:

chr1    
chr2    
chr3    
chr3    
chr10   
chr21   
chrX    
chrY