首页 > 解决方案 > Bash 遍历文件中的重复值

问题描述

我有一个这种格式的文件:

User_ID , Place_ID , Rating 
U32  ,   1305  ,   2 
U32  ,   1276  ,   2 
U32  ,   1789  ,   3 
U65  ,   1985  ,   1 
U65  ,   1305  ,   1 
U65  ,   1276  ,   2 

我想遍历这个文件,排序Place_ID,遍历重复的值Place_ID并添加评级,一旦添加了最后一个元素Place_ID,检查是否value > x如果为真,将 推Place_ID入数组。

例如:Place_ID 1305:2 + 1 / 2 = 1.5 > 1 ----> ids+=($id)

Place_ID 1276: 2 + 2 / 2 = 2 > 1 -----> ids+=($id)

我试过了

test5 () {

id=0
count=0
rating=0
ids=()
ratings=()
for i in `sort -t',' -k 2 ratings.csv`
do  
    aux=`echo "$i"| cut -f2 -d','`
    if (( $id != $aux )); then
        if (( $rating != 0 )); then
            rating=`echo "scale=1; $rating / $count" | bc -l`
            if (( $(echo "$rating >= 1" | bc -l) )); then
                ids+=($id)
                ratings+=($rating)
            fi
        fi
        id=$aux
        count=0
        rating=0
    else                        
        rating=$(($rating + `echo "$i"| cut -f3 -d','`))
        count=$(($count + 1))
    fi
done

echo ${#ids[@]}
echo ${#ratings[@]}
}

编辑:我认为它有效,但有没有办法让它变得更好?不会强迫我使用尽可能多的 if 和 count 的东西。

谢谢您的帮助。

标签: bash

解决方案


这是使用 lessif的另一个选项:

#!/bin/bash

sum=()
count=()

while read -r line; do

    place=$(echo "$line" | cut -d',' -f2)
    rating=$(echo "$line" | cut -d',' -f3)

    sum[$place]=$(echo "$rating + ${sum[$place]-0}" | bc -l)
    count[$place]=$((count[$place] + 1))

done < <( sed 1d ratings.csv | sort -t',' -k 2 | tr -d '[:blank:]' )

ratings=()
for place in "${!sum[@]}"; do
    ratings[$place]=$(echo "scale=1; ${sum[$place]} / ${count[$place]}" | bc -l)
done

# ratings at this point has the ratings for each place
echo ${!ratings[@]} # place ids
echo ${ratings[@]} # ratings

我假设你ratings.csv有标题,这就是为什么sed 1d ratings.csv


推荐阅读