2

For example, if my file looks like this:

string
string1
string2
string4
string800
value2
value3
value5
value10
something18
something20   

I want the output to be

string800 
value10
something20

The word before the numbers could be anything, but when I said "where a pattern is matched" I meant that I want to keep the highest number where the word before the number is the same, for example, 800 is higher than 10 and 20, but I still want to keep the numbers containing 10 and 20 when the word before is something else than what was before 800, like in my example above.

I need this to work on OSX, so please avoid features that only exist in GNU utilities.

0
3

I don't have an osx awk to try this on, but it works on my 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] } '

On each line we look for the starting index in the line of the regexp pattern that is a number with optional trailing whitespace. We split the line at that index into the word part and the number part. The number string is converted to a number by adding 0 to it. An associative array indexed by the word keeps hold of the biggest number.

1
  • Thanks. This did work on OSX. I do keep GNU awk on my computer, but it's more comfortable to have something that works on a fresh installation. Dec 19 '15 at 16:02
1

If the lines corresponding to a given prefix are always grouped (i.e. all the stringNNN are together, etc.), you can use awk, buffering lines as long as they have the same prefix, then printing out the one with the highest suffix.

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; }'

If the lines corresponding to a given prefix are not always grouped (e.g. you can have foo1 bar1 foo2), you can sort the file first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.