3

我正在试验 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”)分开,并从每个组中选择得分最高的字符串。
在这种情况下,组“have.a.nice.day”将是“have.a.nice.day.c”,组“go.to.sleep”将是“go.to.sleep.b”,
所以我想最好的办法是分离元素并递归地为它们分配变量。像这样:

#!/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  

但现在我不知道如何为每组找到最好的分数。
谢谢

4

1 回答 1

3

因此,我认为您的实际问题是如何获取已标记为“输出”的“输入文本”,并找到数字最高的行?

假设您的输出是输入,我将使用 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
于 2012-10-09T23:21:18.133 回答