我有一个格式的文件
用户身份
经纬度时间戳
经纬度时间戳
用户身份
经纬度时间戳
经纬度时间戳
经纬度时间戳
等等
我想拆分文件然后做这种事情
cat data.txt | sort | awk '{print $1" "$2;}' | uniq -c | sort
所以我可以获得每个用户的每个唯一位置出现的次数。
它在 Perl 中相对简单:
perl -lnae 'if (scalar(@F) == 1) { $userid = $F[0]; next; }
$sum{$userid}->{"$F[0] $F[1]"}++;
END { foreach my $userid (sort keys %sum)
{
foreach my $posn (sort keys %{$sum{$userid}})
{
printf "%-15s %-15s %3d\n", $userid, $posn, $sum{$userid}{$posn};
}
}
}'
给定一个输入文件:
user1
23.42 39.11 2013-01-01T00:00:00-00:00
23.52 39.61 2013-01-02T00:00:00-00:00
23.42 39.11 2013-01-03T00:00:00-00:00
user2
53.42 29.11 2013-01-01T00:00:00-00:00
43.52 19.61 2013-01-02T00:00:00-00:00
23.42 39.11 2013-01-03T00:00:00-00:00
43.52 19.61 2013-01-04T00:00:00-00:00
43.52 19.61 2013-01-05T00:00:00-00:00
奇怪的信天翁(又名user1
和user2
)可以在以下位置找到:
user1 23.42 39.11 2
user1 23.52 39.61 1
user2 23.42 39.11 1
user2 43.52 19.61 3
user2 53.42 29.11 1
处理它awk
并不那么直截了当。特别是,在 中完成排序会很痛苦awk
,所以它会被推迟到sort
程序中:
如果文件x19.awk
包含(shell)脚本:
awk 'BEGIN { SUBSEP = "\t" }
NF == 1 { userid = $1; next; }
{ count[userid, $1, $2]++; }
END { for (i in count) print i "\t" count[i]; }'
并且上面的数据文件是x19.data
,那么这个 shell 命令会产生如下所示的输出:
$ sh x19.awk < x19.data | sort -k1,1 -k2,2n -k3,3n | pr -e4 -l1 -t
user1 23.42 39.11 2
user1 23.52 39.61 1
user2 23.42 39.11 1
user2 43.52 19.61 3
user2 53.42 29.11 1
$
假设一行是用户 ID,如果它少于 3 列,并且您的 lat 和 lon 数据不包含任何空格,您可以简单地执行以下操作:
awk 'BEGIN{ cmd = "sort | uniq -c" }
NF < 3 { close cmd; print; next }
{ print $1, $2 | cmd }' input-file