Ned
Ned

Reputation: 131

sed extract digits

I try to extract digits with sed:

echo hgdfjg678gfdg kjg45nn | sed 's/.*\([0-9]\+\).*/\1/g'

but result is: 5 How to extract: 678 and 45? Thanks in advance!

Upvotes: 13

Views: 38221

Answers (4)

plhn
plhn

Reputation: 5263

.* in sed is greedy. And there are no non-greedy option AFAIK.
(You must use [^0-9]* in this case for non-greedy matching. But this works only once, so you will get only 678 without 45.)

If you must use only sed, it would not be easy to get the result.
I recommend to use gnu’s grep

$ echo hgdfjg678gfdg kjg45nn | grep -oP '\d+'
678
45

If you really want to stick to sed, this would be one of many possible answers.

$ echo hgdfjg678gfdg kjg45nn | \
sed -e 's/\([0-9^]\)\([^0-9]\)/\1\n\2/g' | \
sed -n 's/[^0-9]*\([0-9]\+\).*/\1/p’
678
45

Upvotes: 2

Fredrik Pihl
Fredrik Pihl

Reputation: 45662

Or use tr:

$ echo hgdfjg678gfdg kjg45nn | tr -d [a-z]
678 45

Upvotes: 3

Victor Vasiliev
Victor Vasiliev

Reputation: 462

You may use grep with option -o for this:

$ echo hgdfjg678gfdg kjg45nn | grep -E -o "[0-9]+"
678
45

Upvotes: 9

hmakholm left over Monica
hmakholm left over Monica

Reputation: 23332

The problem is that the . in .* will match digits as well as non-digits, and it keeps on matching as long as it can -- that is as long as there's one digit left unconsumed that can match the [0-9].

Instead of extracting digits, just delete non-digits:

echo hgdfjg678gfdg kjg45nn | sed 's/[^0-9]//g'

or even

echo hgdfjg678gfdg kjg45nn | tr -d -c 0-9

Upvotes: 22

Related Questions