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 に答える