如果数据如下所示:
a,b,3
c,d,e,f,2
g,1
我想按最后一列排序。 结果应该是:
g,1
c,d,e,f,2
a,b,3
如果最后一个字段是个位数
$ rev file | sort | rev
您可能需要添加-t, -n
来对数字排序,但个位数没关系。
或者,对于awk
的一般情况
$ awk -F, '{a[$NF]=$0} END{n=asorti(a,d); for(k=1;k<=n;k++) print a[d[k]]}' file
g,1
c,d,e,f,2
a,b,3
如果最后一个字段不唯一,此操作将失败。 使用装饰/排序/非装饰成语,你可以写(当你发现自己一样(
$ awk -F, '{print $NF FS $0}' file | sort -n | cut -d, -f2-
在键和记录之间使用字段分隔符更安全,因为您希望确保 FS 不会出现在键本身中。
我有一个愚蠢但简单的方法来做到这一点:)
如果文件中的原始数据:~/桌面/1.log
$ awk -F, '{print$NF, $0}' ~/Desktop/1.log | sort -n | awk '{print $2}'
克,1
C,D,E,F,2
甲,乙,3
这是我使用 bash 脚本的解决方案——我将其命名为uncertain.sh
。
# Set here the size of the largest item to sort.
# In our case it is c,d,e,f,2 which is size 5.
max_n=5
# This function 'pads' array with P's before last element
# to force it to grow to max_n size.
# For example, (a b 3) will be transformed into (a b P P 3).
pad () {
local arr=("$@")
local l=${#arr[@]}
local diff_l=$((max_n-l))
local padding=""
# construct padding
for i in `seq 1 $diff_l`; do
padding+="P "
done
local l_minus=$((l-1))
arr=(${arr[@]:0:$l_minus} "$padding"${arr[@]:$l_minus})
echo "${arr[@]}"
}
################################################
# Provide A,B,C here to sort by last item
################################################
A="a,b,3"
B="c,d,e,f,2"
C="g,1"
A=$(echo "$A" | tr ',' ' ')
B=$(echo "$B" | tr ',' ' ')
C=$(echo "$C" | tr ',' ' ')
a=(`echo "$A"`)
b=(`echo "$B"`)
c=(`echo "$C"`)
# Get padded arrays.
a=$(pad "${a[@]}")
b=$(pad "${b[@]}")
c=$(pad "${c[@]}")
# Here, we sort by the last field (we can do this since
# padded arrays are all same size 5).
# Then we remove 'P's from strings.
feed=$(printf "%sn" "$a" "$b" "$c" | sort -k5,5n | tr -d 'P')
# Lastly, we change spaces with commas ','.
while read line; do
echo "$line" | tr -s ' ' | tr ' ' ','
done < <(echo "$feed")
这是输出
$ ./uncertain.sh
g,1
c,d,e,f,2
a,b,3
这是我是如何做到的:
我们从
a,b,3
c,d,e,f,2
g,1
我们将其转换为
a,b,P,P,3
c,d,e,f,2
g,P,P,P,1
然后我们可以按第 5 列排序,因为它们的大小都相同 5。
所以这变成了
g,P,P,P,1
c,d,e,f,2
a,b,P,P,3
我们现在可以删除 P。
g,1
c,d,e,f,2
a,b,3
希望你觉得这有用。