【问题标题】:How to sort multiple rows from Lowest to Highest value?如何将多行从最低值排序到最高值?
【发布时间】:2019-10-10 04:44:32
【问题描述】:

我正在尝试获取超过 800 行的多个数据集,并将每一行从最低值到最高值进行排序。数据中的每一行用于一个基因/一组变体(染色体:position_reference/alternative,例如 22:42721284_C/T),以制表符分隔。每行的第一个元素是基因(例如gene1、gene2、gene3 等),该行的其余部分用于以22:42721284_C/T 形式编写的变体ID。每个基因有多少变体会有所不同。 我拥有的文件现在是从最高位置到最低位置(42721284、42721258、42721203)排序的,但我想从最低位置到最高位置对文件进行排序。

我的文件:

Gene1 22:42721284_C/T 22:42721258_A/G 22:42721203_A/G …etc
Gene2 22:50483983_C/T 22:50483960_C/G 22:50483951_C/T …etc
Gene3 22:24429129_A/G 22:24428893_A/G 22:24428885_C/T …etc

我尝试了不同的黑色命令(例如 black -V),但我没有得到从最低到最高的输出。我更喜欢 awk(或 gawk)解决方案,但我对编码完全陌生,因此将不胜感激。

期望的输出:

Gene1 22:42721203_A/G 22:42721258_A/G 22:42721284_C/T …etc
Gene2 22:50483951_C/T 22:50483960_C/G 22:50483983_C/T …etc 
Gene3 22:24428885_C/T 22:24428893_A/G 22:24429129_A/G …etc

【问题讨论】:

    标签: linux sorting awk


    【解决方案1】:
    • xargs 文件运行中的每一行
    • sh -c一个shell脚本
    • first="$1"; shift 保存第一个参数以备后用
    • printf "%s\n" "$@" - 在单独的行上打印其余参数
    • sort - 按字母顺序排序
    • tr "\n" " " | sed "s/ $//" - 用空格替换换行符并删除尾随的换行符。
    • 用 printf 打印输出

    脚本:

    cat <<EOF >file
    Gene1 22:42721284_C/T 22:42721258_A/G 22:42721203_A/G
    Gene2 22:50483983_C/T 22:50483960_C/G 22:50483951_C/T
    Gene3 22:24429129_A/G 22:24428893_A/G 22:24428885_C/T
    EOF
    
    <file xargs -l -P1 sh -c '
        first=$1
        shift
        printf "%s %s\n" "$first" "$(
            printf "%s\n" "$@" |
            sort |
            tr "\n" " " | sed "s/ $//"
        )"
    ' -- >output
    
    # the same using plain bash while read loop
    if false; then
    while IFS=' ' read -r first rest; do
        echo "$first" "$(
            <<<"$rest" tr ' ' '\n' |
            sort |
            tr "\n" " " | sed "s/ $//"
        )"
    done <file >output
    fi
    
    cat <<EOF >expected
    Gene1 22:42721203_A/G 22:42721258_A/G 22:42721284_C/T
    Gene2 22:50483951_C/T 22:50483960_C/G 22:50483983_C/T
    Gene3 22:24428885_C/T 22:24428893_A/G 22:24429129_A/G
    EOF
    
    diff output expected
    

    【讨论】:

      【解决方案2】:

      使用 GNU awk 进行 asort():

      $ cat tst.awk
      BEGIN { FS=OFS="\t" }
      {
          printf "%s%s", $1, OFS
          sub("^[^"FS"]*"FS,"")
          split($0,vars)
          n = asort(vars)
          for (i=1; i<=n; i++) {
              printf "%s%s", vars[i], (i<n ? OFS : ORS)
          }
      }
      
      $ awk -f tst.awk file
      Gene1   22:42721203_A/G 22:42721258_A/G 22:42721284_C/T …etc
      Gene2   22:50483951_C/T 22:50483960_C/G 22:50483983_C/T …etc
      Gene3   22:24428885_C/T 22:24428893_A/G 22:24429129_A/G …etc
      

      【讨论】:

      • 非常感谢!这正是我想要的。
      猜你喜欢
      • 2018-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多