【问题标题】:Re-order or sort line by line逐行重新排序或排序
【发布时间】:2021-03-07 22:03:36
【问题描述】:

我有一个结构如下的基因组坐标文件:

chromosome1|25000|35000_chromosome1|400|600
chromosome4|78000|80000_chromosome2|43000|45000

我想对每行上的 2 个条目进行排序,如果它们属于同一染色体(例如第 1 行),则首先按较低的基因组坐标排序,如果它们位于不同的染色体上,则首先按编号较低的染色体排序。 期望的输出:

chromosome1|400|600_chromosome1|25000|35000
chromosome2|43000|45000_chromosome4|78000|80000

我尝试了以下方法,但奇怪的是它并不总是正常工作!

cat file | awk 'BEGIN{OFS="\t"}{split($1,a,"_chr"); a[2]="chr" a[2]; str=$1; if(a[1]>a[2]) str=a[2]"_"a[1]; print str,$2}'

可以请人帮忙吗? 提前非常感谢!

【问题讨论】:

    标签: bash sorting awk


    【解决方案1】:

    请您尝试以下方法:

    awk 'BEGIN {FS = OFS = "_"}                # use "_" as a delimiter
    {
        split($1, a, "\\|")                    # split left genomic coordinates with "|" and assign array "a"
        split($2, b, "\\|")                    # split right genomic coordinates with "|" and assign array "b"
        if (a[1] == b[1]) {                    # if they belong to the same chromosome
            if (a[2] < b[2]) print $1, $2      # then compare lower genomic coordinates
            else print $2, $1
        } else {                               # they belong to different chromosomes
            sub(/^[^0-9]+/, "", a[1])          # extract chromosome number and overwrite a[1]
            sub(/^[^0-9]+/, "", b[1])          # extract chromosome number and overwrite b[1]
            if (a[1]+0 < b[1]+0) print $1, $2  # then compare the numbers
            else print $2, $1
        }
    }' file
    

    给定示例文件的输出:

    chromosome1|400|600_chromosome1|25000|35000
    chromosome2|43000|45000_chromosome4|78000|80000
    

    【讨论】:

    • 添加了注释:使用上面的脚本,我收到了警告“awk: cmd.line:1: warning: escape sequence \|' treated as plain |”,因此我只是删除了 split($1, a, "\|") 和 split($1, b, "\|")。再次感谢!
    • 奇怪的是:我已经完成了对所有文件的脚本运行,但在某些情况下它不起作用...我不太确定为什么。这是一个未正确处理的示例:chromosome17|36695929|36696217_chromosome3|189667168|189667457 知道为什么吗?提前谢谢你。
    • 感谢您的测试,很抱歉打扰您。在比较行if (a[1] &lt; b[1]) ... 中,我们期望执行数值比较。但是,某些版本的awk 似乎出于某种原因在此处执行字符串比较。 (也许 a[1] 和 b[1] 在 sub() 操作之前曾经是一个字符串。这可能是awk 的错误。)作为一种解决方法,让我们通过添加“0”来强制一个数字上下文这些变量在这里。另外,“|”问题,说“\\|”会很健壮反而。我已经用这些修改更新了我的答案。希望它现在可以工作。 BR。
    • 我会尝试新版本的,同时非常感谢您的好意和详尽的解释,我学到了很多东西。干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    相关资源
    最近更新 更多