根据密钥从文件中读取最近的条目

Reading recent entry from a file based on a key

输入文件,fruits.txt:

JAN,APPLE 
FEB,MANGO 
JAN,ORANGE 
MAR,APPLE 
FEB,APPLE

预期输出文件:

MAR,APPLE
FEB,APPLE
JAN,ORANGE

为了获得上述输出,使用了以下代码:

#!/bin/sh

declare -A m_arr

cat fruits.txt > /tmp/ID.part

while read line
do
Month=$(echo $line | cut -d, -f1)
Fruits=$(echo $line | cut -d, -f2)
m_arr[${Month}]=${Fruits}
done < /tmp/ID.part

for i in ${!m_arr[@]}
do
echo "$i,${m_arr[$i]}"
done

这适用于输入文件中的少量数据。我有 200 000 个条目并观察到 ​​cut 命令非常慢。也尝试使用 awk,但没有得到更好的结果。我的要求是从 row1 读取文件,key 为 column1。我需要更新每个键的条目。

我认为使用 Awk 可以很容易地完成此操作,您只需要在 </code> 中散列 <code> 的值,一旦您使用 [=14= 分隔文件] 分隔符

awk -v FS=, -v OFS=, '{key[]=; next}END{for (i in key) print i,key[i]}' file

此外,如果你想在处理一百万行文件时加快速度,你可以更改本地化设置以在解析时加快执行速度,你可以在本地将 LC_ALL=C 传递给命令。参见 Stéphane Chazelas's answer on what "LC_ALL=C" does?

在 bash 版本 4 中,您可以声明一个关联数组并用 read 的结果填充它,用自定义 IFS:

拆分您的行
$ declare -A a
$ while IFS=, read key value; do a["$key"]="$value"; done < fruits.txt
$ declare -p a
declare -A a=([MAR]="APPLE" [FEB]="APPLE" [JAN]="ORANGE" )

如果你想从数组中生成特定的输出,你还需要一个循环:

$ for key in "${!a[@]}"; do printf '%s,%s\n' "$key" "${a[$key]}"; done
MAR,APPLE
FEB,APPLE
JAN,ORANGE

使用GNU的最短的datamash:

datamash -st, -g1 last 2 <file
  • g1 - 按第一列分组
  • last 2 - 保留组的最后一个值

输出:

FEB,APPLE
JAN,ORANGE 
MAR,APPLE