输入文件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
这适用于输入文件中的少量数据。我有20万个条目,并观察到切割命令非常慢。也试过awk,没有得到更好的结果。我的要求是从row1读取文件,键为column1。我需要更新每个密钥的条目。
我认为用Awk
可以很容易地做到这一点,一旦你用$1
分隔符分隔文件,你只需要在$2
中散列,
的值
awk -v FS=, -v OFS=, '{key[$1]=$2; 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
- 第1栏组last 2
- 保持该组的最后一个值输出:
FEB,APPLE
JAN,ORANGE
MAR,APPLE