【问题标题】:Using bash to sort data horizontally使用 bash 对数据进行水平排序
【发布时间】:2014-09-23 14:11:10
【问题描述】:

我有一个文件的列中充满了数据

sarah mark john
10    20   5
x     y    z 

我想对数据进行排序,使列保持不变,但第二行按递增顺序排列,因此如下所示:

john sarah mark
5    10    20 
z    x     y 

我一直在查看排序命令,但只能找到垂直排序,而不是水平排序。我很乐意使用任何工具,感谢任何帮助。 谢谢!

【问题讨论】:

  • 所以您只想根据第二列对输出进行排序?

标签: bash sorting


【解决方案1】:

让我们创建一个转置文件的函数(让行变成列,列变成行):

transpose () {
  awk '{for (i=1; i<=NF; i++) a[i,NR]=$i; max=(max<NF?NF:max)}
        END {for (i=1; i<=max; i++)
              {for (j=1; j<=NR; j++) 
                  printf "%s%s", a[i,j], (j<NR?OFS:ORS)
              }
        }'
}

这只是将所有数据加载到二维数组a[line,column],然后将其打印回a[column,line],以便转置给定的输入。包装器transpose () { } 用于将其存储为 bash 函数。您只需将其复制粘贴到您的 shell 中(或者,如果您希望它成为永久功能,则可以在 ~/.bashrc 中,在您打开会话时随时可用)。

然后,通过使用它,我们可以很容易地使用sort -n -k2解决问题:根据第2列进行数字排序。然后,转回。

$ cat a | transpose | sort -n -k2 | transpose
john sarah mark
5 10 20
z x y

如果您想要一个好的格式作为最终输出,只需像这样通过管道传递到column

$ cat a | transpose | sort -n -k2 | transpose | column -t
john  sarah  mark
5     10     20
z     x      y

一步一步:

$ cat a | transpose 
sarah 10 x
mark 20 y
john 5 z
$ cat a | transpose | sort -n -k2
john 5 z
sarah 10 x
mark 20 y
$ cat a | transpose | sort -n -k2 | transpose 
john sarah mark
5 10 20
z x y

【讨论】:

  • 这很好用(谢谢),但在大文件上计算起来似乎非常昂贵。如果我想更快地完成它,我是否坚持将其读入我自己的数据结构并在那里对其进行排序?
【解决方案2】:

来自duplicate question,这将按第一行对列进行排序:

#!/bin/bash

input="$1"

order=$((for i in $(head -1 $input); do echo $i; done) | nl | sort -k2 | cut -f1)

grep ^ $input | (while read line
  do
    read -a columns <<< "${line%"${line##*[![:space:]]}"}"

    orderedline=()
    for i in ${order[@]}
    do
      orderedline+=("${columns[$i - 1]}")
    done
    line=$(printf "\t%s" "${orderedline[@]}")
    echo ${line:1}
  done)

要按第二行排序,请将head -1 $input 替换为head -2 $input | tail -1。如果排序应该是数字,请输入sort -n -k2 而不是sort -k2

【讨论】:

    【解决方案3】:

    良好的单线可以完成工作:

    perl -ane '$,=" "; print sort @F; print "\n";' file

    我在这里找到它:http://www.unix.com/unix-for-advanced-and-expert-users/36039-horizontal-sorting-lines-file-sed-implementation.html

    【讨论】:

    • 这会单独对每一行进行排序,而不是移动列的数据以便对第一行进行排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 2022-08-20
    • 2011-02-02
    • 1970-01-01
    相关资源
    最近更新 更多