庆典 - 匹配和选择字符串

问题描述:

的最好成绩,我用的bash脚本的实验,需要帮助解决这个:
我有一个文本文件中的以下数据:(test.txt的)庆典 - 匹配和选择字符串

have.a.nice.day.a=42and55 
have.a.nice.day.b=0 
have.a.nice.day.c=55and67 
go.to.sleep.a=111 
go.to.sleep.b=2and122and33 
go.to.sleep.c=64 

我想要将字符串与匹配分数和分隔符(本例中为“and”)的分数分开,并从每个分组中选出得分最高的字符串。
在这种情况下,对于组“go.to.sleep”
,对于组“have.a.nice.day”和“go.to.sleep.b”将是“have.a.nice.day.c” 所以我认为最好的办法是将元素分开并递归地赋予它们变量。像这样:

#!/bin/bash 
names=$(cat test.txt | grep -o -P '.+(?==\d+)') 
for name in $names 
do 
    echo -n "$name"" " 
    scores=$(cat test.txt | grep -o -P '(?<='$name'=).+') 
    for scores_group in $scores 
    do 
    single_score=$(echo $scores_group | grep -o -P '\d+') 
    for score in $single_score 
    do 
     echo -n "$score"" " 
    done 
    echo 
    done 
done 

输出将是:

have.a.nice.day.a 42 55 
have.a.nice.day.b 0 
have.a.nice.day.c 55 67 
go.to.sleep.a 111 
go.to.sleep.b 2 122 33 
go.to.sleep.c 64 

,但现在我不知道如何找到每个组的最好成绩。
谢谢

+1

什么是最终目标?效率还是学习bash? –

+0

最终目标是学习bash – buntuser

所以,你的实际问题,我认为,你如何把你已经标记为“输出”的“输入文本”,并找到最高数量的行?

假设你的输出输入,我会使用awk做到这一点:

$ awk '{name=$1; item=$1; sub(/\.[^.]+$/,"",name); sub(/.*\./,"",item); for (i=2; i<=NF; i++) {if($i>highest[name]){highest[name]=$i;which[name]=item}}} END{for(name in highest){printf("%s = %s = %s\n",name,which[name],highest[name])}}' input.txt 
go.to.sleep = b = 122 
have.a.nice.day = c = 67 

或者,为了解释爆发了:

{ 

    # Get the parts of the first field... 
    name=$1; sub(/\.[^.]+$/,"",name); 
    item=$1; sub(/.*\./,"",item); 

    # Walk through the scores, record the highest in an array 
    for (i=2; i<=NF; i++) { 
    if ($i>highest[name]) { 
     highest[name]=$i; 
     which[name]=item; 
    } 
    } 
} 

# Now, step through the resultant array 
END { 
    for (name in highest) { 
    printf("%s = %s = %s\n",name,which[name],highest[name]); 
    } 
} 

请问这个怎么办?还是你真的想要在纯粹的bash中实现这个?如果是这样,上面的awk可以用下面的bash表示:

#!/bin/bash 

declare -A highest 
declare -A which 

while read word scores; do 
    name=${word%.*} 
    item=${word##*.} 
    set -- $scores 
    while [[ -n "$1" ]]; do 
     if [[ $1 -gt highest[$name] ]]; then 
      highest[$name]=$1 
      which[$name]=$item 
     fi 
     shift 
    done 
done < input.txt 

for name in "${!highest[@]}"; do 
    printf "%s = %s = %s\n" "$name" "${which[$name]}" "${highest[$name]}" 
done 
+0

这会得到我的投票。我仍然最喜欢'awk' :-) – Steve

+0

谢谢ghoti,我正在研究你的答案.. – buntuser

+0

甚至经过几个小时的阅读bash手册和例子,我仍然在这里输了.. – buntuser