bash按字母顺序排序和粘贴列

时间:2017-05-24 07:30:09

标签: bash awk

我有一个file.txt,其中包含以下列

id  chr pos alleleA alleleB
1   01  1234    CT  T
2   02  5678    G   A
3   03  8901    T   C
4   04  12345   C   G
5   05  567890  T   A

我正在寻找一种创建新列的方法,使其看起来像:chr:pos:alleleA:alleleB 问题是alleleA和alleleB应该基于以下方式排序: 字母顺序 2.这两列中的任何一列应该首先是每行更多的字母,然后是第二列

在这个例子中,它看起来像这样:

id  chr pos alleleA alleleB newID
1   01  1234    CT  T   chr1:1234:CT:T
2   02  5678    G   A   chr2:5678:A:G
3   03  8901    T   C   chr3:8901:C:T
4   04  12345   C   G   chr4:12345:C:G
5   05  567890  T   A   chr5:567890:A:T

我感谢任何帮助和建议。感谢。

修改 到目前为止,我可以修改chr列,使其外观为“chr:1”...

应该合并

AlleleAAlleleB列,以便如果任一列包含多于1个字母,则在newID列中,它将位于第一位。如果两列中只有一个字母,则这些字母按字母顺序排列在newID

2 个答案:

答案 0 :(得分:1)

Perl救援:

perl -lane '
    if (1 == $.) { print "$_ newID" }
    else { print "$_ ", join ":", "chr" . ($F[1] =~ s/^0//r),
                                  $F[2],
                                  sort { length $b <=> length $a
                                         or $a cmp $b
                                  } @F[3,4];
    }' -- input.txt
  • -l从输入中删除换行符并将其添加到print
  • -n逐行读取输入行
  • -a将空格上的每个输入行拆分为@F数组
  • $.是输入行号,条件只打印第一行的标题
  • s/^0//从$ F [1](即第2列)
  • 中删除初始零
  • /r返回替换结果
  • 比较最后两列长度,如果它们相同,则使用字符串比较。

答案 1 :(得分:1)

gawk 解决方案:

awk 'function custom_sort(i1,v1,i2,v2){   # custom function to compare 2 crucial fields
         l1=length(v1); l2=length(v2);    # getting length of both fields
         if (l1 == l2) { 
             return (v1 > v2)? 1:-1  # compare characters if field lengths are equal
         } else { 
             return l2 - l1          # otherwise - compare by length (descending)
         }   
     } NR==1 { $0=$0 FS "newID" }  # add new column
       NR>1 { a[1]=$4; a[2]=$5; asort(a,b,"custom_sort"); # sort the last 2 columns using function `custom_sort`
       $(NF+1) = sprintf("chr%s:%s:%s:%s",$1,$3,b[1],b[2])
     }1' file.txt | column -t

输出:

id  chr  pos     alleleA  alleleB  newID
1   01   1234    CT       T        chr1:1234:CT:T
2   02   5678    G        A        chr2:5678:A:G
3   03   8901    T        C        chr3:8901:C:T
4   04   12345   C        G        chr4:12345:C:G
5   05   567890  T        A        chr5:567890:A:T