我有一个类似的文件:
FILE.DAT
1 2
1 3
2 1
2 4
2 3
3 4
左列已排序。我想写一个新文件谎言:
1 2 3
2 1 4 3
3 4
在第一列中,应该是file.dat的左列号,并且在它旁边是右列号。有什么帮助吗?
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分:2)
这也有效
awk '{a[$1]=a[$1]$2" "} END {for (i in a) {print i,a[i]}}' temp.txt
答案 4 :(得分: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