AWK对数字块进行数字排序/行

时间:2016-09-12 13:53:13

标签: sorting awk

我有一个文本文件:

aa 
80,143
60,312
50,123
20,14
bb
cc
80,163
60,132
50,23
20,48

我希望每次找到一个数字块时,将行数从最小的数字排序到最大...

预期结果应如下所示:

aa 
20,14
50,123
60,312
80,143
bb
cc
20,48
50,23
60,132
80,163

如何调用sort函数来实现这一目标?

3 个答案:

答案 0 :(得分:1)

也许最简单的是使用awk和朋友

来装饰/排序/不合理的方法
$  awk '{if(!/[0-9,]/) {c++;d=0} else {d=1} print c "." d "," $0}' file |
   sort -nt, | 
   cut -d, -f2-

aa
20,14
50,123
60,312
80,143
bb
cc
20,48
50,23
60,132
80,163

答案 1 :(得分:1)

最新版本的TXR语言有一个awk macro,它实现了TXR Lisp语法和语义的Awk范例。

可能的解决方案如下:

;; sort list of (integer string) by the integer, ascending,
;; then extract the list of strings from the sorted result,
;; and dump it as a list of lines with tprint.

(defun sort-dump (num-rec-pairs)
  (tprint [mapcar second [sort num-rec-pairs < first]]))

;; Awk job

(awk (:begin (set fs "," ofs ","))           ;; set up I/O field separators
     (:let list)                             ;; bind local variable "list"

     ;; if we have two fields ...
     ((= nf 2) (mf int-str)                  ;; map string fields to integers
               (push (list [f 0] rec) list)) ;; push (field rec) pair to list

     ;; if we have one field ...
     ((= nf 1) (sort-dump list)              ;; dump the list
               (set list nil)                ;; clear the list
               (prn))                        ;; print current record

     (:end (sort-dump list)))                ;; dump list at end of awk job

执行命令

$ txr sort.tl data
aa 
20,14
50,123
60,312
80,143
bb
cc
20,48
50,23
60,132
80,163

答案 2 :(得分:0)

这适用于您提供的示例输入,并且适用于您未提供的更有趣的输入(请参阅我在您的问题下的评论):

$ cat tst.awk
function prtArr(        a,b) {
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (a in arr) {
        for (b in arr[a]) {
            print a, b
        }
    }
    delete arr
}
BEGIN { FS=OFS="," }
/^[0-9,]+$/ { arr[$1][$2]; next }
{ prtArr(); print }
END { prtArr() }

$ awk -f tst.awk file
aa
20,14
50,123
60,312
80,143
bb
cc
20,48
50,23
60,132
80,163

以上使用GNU awk 4. *表示真正的多维数组和sorted_in。