我有一个名为prices.csv的csv文件,如下所示:
Name, Price, Description
Apple, 2.85, fruit
Kiwi, 1.96, fruit
Banana, 0.99, fruit
Peach, Not available, fruit
Orange, 2.02, fruit
我想按升序对第二列(价格)进行排序,除了“不可用”的值外,这些值应放在底部。
到目前为止,我所做的是:
sort -t, -k2,2 -n prices.csv > ordered_prices.csv
这将创建以下文件:
Name, Price, Description
Peach, Not available, fruit
Banana, 0.99, fruit
Kiwi, 1.96, fruit
Orange, 2.02, fruit
Apple, 2.85, fruit
如您所见,这会将价格为“不可用”的产品放在顶部而不是底部。如何使用通用代码将文本放在底部?
答案 0 :(得分:2)
如果您有gnu-awk
,则可以使用PROCINFO
:
awk -F ', ' 'NR == 1 {
print
next
}
$2+0 == $2 {
a[NR] = $2
rec[NR] = $0
next
}
{
rest = rest $0 RS
}
END {
PROCINFO["sorted_in"] = "@val_num_asc"
for (i in a)
print rec[i]
printf "%s", rest
}' file
Name, Price, Description
Banana, 0.99, fruit
Kiwi, 1.96, fruit
Orange, 2.02, fruit
Apple, 2.85, fruit
Peach, Not available, fruit
或者,您可以使用head + tail + sort
命令,如下所示:
head -n 1 file && sort -t, -k2V <(tail -n +2 file)
答案 1 :(得分:1)
您可以考虑使用版本排序而不是数字排序:
$ sort -t, -k2,2V prices.csv > ordered_prices.csv
有关版本排序的更多信息,请参见here。请注意,这会将标头移到后面。您可以使用此方法:
$ OUTPUTFILE=outputfile
$ awk -v out="$OUTPUTFILE" '(NR==1){print > out; close(out)}(NR>1)' inputfile \
| sort -t, -k2,2V > $OUTPUTFILE
但这太丑陋了,在这一点上,我将切换到Anubhava的解决方案。
您可以执行此操作的另一种方法是进行可笑的替换:
$ sed '2,$s/\([[:alpha:]]\+\)/999999\1/g' | sort -t, -k2n | sed 's/999999//g'
将标题保留在原处。