パターンに一致する最も高い番号の行を維持する方法は?

パターンに一致する最も高い番号の行を維持する方法は?

たとえば、私のファイルが次のような場合:

string
string1
string2
string4
string800
value2
value3
value5
value10
something18
something20   

私が望む出力は

string800 
value10
something20

数字の前の単語は何でも構いませんが、「パターンが一致する位置」と言うと、同じ最も高い数字を持つ数字の前に単語を保持したいという意味です。たとえば、800 は 10 と 20 よりも高いが、前の単語が 800 より前ではない場合でも、上記の例のように 10 と 20 を含む数字を保持したいと思います。

OSXで動作するにはこれが必要なので、GNUユーティリティにのみ存在する機能を避けてください。

答え1

私はこれを試すosxを持っていませんが、awk私のLinux gnu awkで動作します。

awk '
{ n = match($0, /[0-9]+ *$/);
  if(n){
    word = substr($0, 1, n - 1); num = 0 + substr($0, n);
    if(!(word in max) || max[word] < num) max[word] = num
  }
}
END{ for(word in max)print word max[word] } '

各行の正規表現パターンの行で開始インデックスを探します。このインデックスはオプションの末尾のスペースを含む数値です。そのインデックスの行を単語部分と数字部分に分割します。数値文字列に0を加算して数値に変換します。単語で索引付けされた連想配列は、最大数を保持します。

答え2

与えられたプレフィックスに対応する行が常にグループ化されている場合(たとえば、すべての行がstringNNN一緒にあるなど)、awkを使用して同じプレフィックスを持つ行をバッファリングしてから、最も高い接尾辞を持つ行を印刷できます。

awk '{
    match($0, /[0-9]*/);
    current_prefix = substr($0, 1, RSTART);
    current_number = substr($0, RSTART, RLENGTH);
    if (current_prefix == previous_prefix) {
        if (current_number > max_number) max_number = current_number;
    } else {
        if (NR != 1) print previous_prefix max_number;
        previous_prefix = current_prefix;
        max_number = current_number;
    }
}
END { if (NR != 1) print previous_prefix max_number; }'

与えられたプレフィックスに対応する行が常にグループ化されていない場合(たとえばfoo1 bar1 foo2)、最初にファイルをソートできます。

関連情報