1

我有一个像这样的文件:

文件.dat

1 2
1 3
2 1
2 4
2 3
3 4

左列已排序。我想写一个新文件,如下所示:

1 2 3
2 1 4 3
3 4

第一列应该是 file.dat 的左列编号,旁边是右列编号。有什么帮助吗?

4

5 回答 5

3
#!/bin/bash
awk -f <(cat - <<-'EOF'
  {
    b[$1, a[$1]++] = $2;
  }
  END {
    for (i in a) {
      printf "%d ", i;
      for (j = 0; j < a[i]; j++) {
        printf "%d ", b[i, j];
      }
      print ""
    }
  }
EOF
) < /dev/stdin

输出:

$ ./script.sh < file.dat 
1 2 3 
2 1 4 3 
3 4 

该脚本将与awk. 名称如果file.awk

{
    b[$1, a[$1]++] = $2;
}
END {
    for (i in a) {
        printf "%d ", i;
        for (j = 0; j < a[i]; j++) {
            printf "%d ", b[i, j];
        }
        print ""
    }
}

像这样运行:

 awk -f file.awk < file.dat
于 2013-02-01T21:41:23.243 回答
3

这些答案不需要将整个文件存储在内存中。它们都要求对文件进行排序。

awk:

awk '
    $1 != prev {
        if (NR > 1) print ""
        printf "%d %d", $1, $2
        prev=$1
        next
    } 
    {printf " %d", $2} 
    END {print ""}
' file.dat

等效的bash:

prev=""
while read a b; do
    if [[ $prev != $a ]]; then
        [[ -n $prev ]] && echo
        printf "%d %d" $a $b
        prev=$a
    else
        printf " %d" $b
    fi
done < file.dat
echo
于 2013-02-02T01:15:59.110 回答
2

好吧,您已经接受了答案。但是,我想为您的有趣问题添加另一个更简单(也许)的简短单行。

awk '$1 in a{a[$1]=a[$1]" "$2;next}{a[$1]=$0}END{for(i in a)print a[i]}' file

看到它与您的示例一起使用:

kent$  cat test.txt
1 2
1 3
2 1
2 4
2 3
3 4

kent$  awk '$1 in a{a[$1]=a[$1]" "$2;next}{a[$1]=$0}END{for(i in a)print a[i]}' test.txt
1 2 3
2 1 4 3
3 4
于 2013-02-02T00:01:46.133 回答
2

这也有效

awk '{a[$1]=a[$1]$2" "} END {for (i in a) {print i,a[i]}}' temp.txt

于 2013-02-02T07:35:30.967 回答
0

这是一种使用方法awk

awk '{ a[$1] = (a[$1] ? a[$1] FS : "") $2 } END { for (i in a) print i, a[i] | "sort" }' file

结果:

1 2 3
2 1 4 3
3 4
于 2013-02-02T01:00:43.397 回答