我可以使用哪些linux命令对选项卡分隔的文本文件中的列进行排序?

时间:2017-07-13 16:44:57

标签: linux sorting awk

我需要比较同一文件的两个版本。两者都是制表符分隔的,并具有以下形式:

<filename1><tab><Marker11><tab><Marker12>...
<filename2><tab><Marker21><tab><Marker22><tab><Marker22>...

因此每一行都有不同数量的标记(数字在1到10之间变化),它们都来自一小组可能的标记。所以文件看起来像这样:

fileX<tab>Z<tab>M<tab>A
fileB<tab>Y
fileM<tab>M<tab>C<tab>B<tab>Y

我需要的是:

  1. 按行排序文件
  2. 对每行中的标记进行排序,使其按字母顺序排列
  3. 因此,对于上面的示例,结果将是

    fileB<tab>Y
    fileM<tab>B<tab>C<tab>M<tab>Y
    fileX<tab>A<tab>M<tab>Z
    

    使用sort轻松做#1但我该如何做#2?

    更新:它不是this post的副本,因为我的行长度不同,我需要每个行(文件名后的条目)单独排序,即唯一保留的列是第一个。

2 个答案:

答案 0 :(得分:1)

awk 解决方案:

awk 'BEGIN{ FS=OFS="\t"; PROCINFO["sorted_in"]="@ind_str_asc" }
     { split($0,b,FS); delete b[1]; asort(b); r=""; 
         for(i in b) r=(r!="")? r OFS b[i] : b[i]; a[$1] = r 
     }
     END{ for(i in a) print i,a[i] }' file

输出:

fileB   Y
fileM   B   C   M   Y
fileX   A   M   Z
  • PROCINFO["sorted_in"]="@ind_str_asc" - 排序模式

  • split($0,b,FS); - 通过b(字段分隔符)将行拆分为数组FS

  • asort(b) - 排序标记

答案 1 :(得分:1)

您只需要:

awk '
{ for (i=2;i<=NF;i++) arr[$1][$i] }
END {
    PROCINFO["sorted_in"] = "@ind_str_asc"
    for (i in arr) {
        printf "%s", i
        for (j in arr[i]) {
            printf "%s%s, OFS, arr[i][j]
        }
        print ""
    }
}
' file

以上使用GNU awk表示真正的多维数组加上sorted_in