hadooper
hadooper

Reputation: 746

Extract last digits from each word in a string with multiple words using bash

Given a string with multiple words like below, all in one line:

first-second-third-201805241346 first-second-third-201805241348 first-second-third-201805241548 first-second-third-201705241540

I am trying to the maximum number from the string, in this case the answer should be 201805241548

I have tried using awk and grep, but I am only getting the answer as last word in the string.

I am interested in how to get this accomplished.

Upvotes: 0

Views: 118

Answers (4)

agc
agc

Reputation: 8446

Gnarly pure bash:

n='first-second-third-201805241346 \
   first-second-third-201805241348 \
   first-second-third-201805241548 \
   first-second-third-201705241540'
z="${n//+([a-z-])/;p=}"
p=0 m=0 eval echo -n "${z//\;/\;m=\$((m>p?m:p))\;};m=\$((m>p?m:p))"
echo $m

Output:

201805241548

How it works: This code constructs code, then runs it.

  1. z="${n//+([a-z-])/;p=}" substitutes non-numbers with some pre-code -- setting $p to the value of each number, (useless on its own). At this point echo $z would output:

    ;p=201805241346 \ ;p=201805241348 \ ;p=201805241548 \ ;p=201705241540
    
  2. Substitute the added ;s for more code that sets $m to the greatest value of $p, which needs eval to run it -- the actual code the whole line with eval runs looks like this:

    p=0 m=0
    m=$((m>p?m:p));p=201805241346
    m=$((m>p?m:p));p=201805241348
    m=$((m>p?m:p));p=201805241548
    m=$((m>p?m:p));p=201705241540
    m=$((m>p?m:p))
    
  3. Print $m.

Upvotes: 1

ctac_
ctac_

Reputation: 2491

Another awk

echo 'first-...-201705241540' | awk -v RS='[^0-9]+' '$0>max{max=$0} END{print max}'

Upvotes: 1

uzsolt
uzsolt

Reputation: 6037

echo 'first-second-third-201805241346 first-second-third-201805241348 first-second-third-201805241548 first-second-third-201705241540' |\
 grep -o '[0-9]\+' | sort -n | tail -1

The relevant part is grep -o '[0-9]\+' | sort -n | tail -n 1.

Upvotes: 3

anubhava
anubhava

Reputation: 785791

Using single gnu awk command:

s='first-second-third-201805241346 first-second-third-201805241348 first-second-third-201805241548 first-second-third-201705241540'
awk -F- -v RS='[[:blank:]]+' '$NF>max{max=$NF} END{print max}' <<< "$s"

201805241548

Or using grep + awk (if gnu awk is not available):

grep -Eo '[0-9]+' <<< "$s" | awk '$1>max{max=$1} END{print max}'

Upvotes: 2

Related Questions