1

I have this string:

1024.00 MB transferred (912.48 MB/sec)

and I need to get only the number 912.48 and transform it in 912,48 with a bash script. I tried to do sed 's/[^0-9.]*//g' but in this way i get 1024.00 912.18. How can I do it?

8 Answers 8

2

So far, every answer here is using external tools (sed, awk, grep, tr, etc) rather than sticking to native bash functionality. Since spinning up external processes has a significant constant-time performance impact, it's generally undesirable when only processing a single line of content (for long streams of content, an external tool will often be more efficient).

This one uses built-ins only:

# one-time setup: set the regex
re='[(]([0-9.]+) MB/sec[)]'
string='1024.00 MB transferred (912.48 MB/sec)'

if [[ $string =~ $re ]]; then  # run enclosed code only if regex matches
  val=${BASH_REMATCH[1]}       # refer to first (and only) match group
  val_with_comma=${val//./,}   # replace "." with "," in that group
  echo "${val_with_comma}"     # ...and emit our output
fi

...yielding:

912,48
Sign up to request clarification or add additional context in comments.

Comments

1

A combination of awk and sed:

str='1024.00 MB transferred (912.48 MB/sec)'
echo "$str" | awk '{print $4}' | sed 's/(//;s/\./,/'

912,48

Or entirely with awk:

echo "$str" | awk '{sub("[(]","");sub("[.]",",");print $4}'

Comments

1

this should work

$ sed -r 's/.*\(([0-9.]+).*/\1/;s/\./,/'

3 Comments

I'd use /^.*\(([0-9.]+).*$/ for extra paranoia, but YMMV.
sed: 1: "/^.*(([0-9.]+).*$/": RE error: parentheses not balanced
@SegFault you omitted the backslash before the first left parenthesis.
1
echo "1024.00 MB transferred (912.48 MB/sec)" | cut -f2 -d'(' | cut -f1 -d' ' | sed 's/\./,/'

2 Comments

if you're avoiding sed, go all the way and change to tr '.' ',' as well.
@karakfa, I wasn't trying to avoid sed. Just using a different approach. Thanks for the "tr" suggestion.
0
echo "1024.00 MB transferred (912.48 MB/sec)" | cut -d " " -f4 | tr "." "," | tr -d "("

Comments

0

Another of the near-infinite possibilities:

read x y < <(tr -dc '[0-9. ]' <<< "1024.00 MB transferred (912.48 MB/sec)")
echo ${y}

or

grep -oP '(?<=\()[\d.]+' <<< "1024.00 MB transferred (912.48 MB/sec)"

Comments

0

Here is an awk to get the job done:

s='1024.00 MB transferred (912.48 MB/sec)'
awk -F '[() ]+' '{sub(/\./, ",", $4); print $4}' <<< "$s"

912,48

Comments

0

wow, so many answers :)

here's mine, should be pretty fast:

grep -o '([^ ]\+' | tail -c+2 | tr '.' ','

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.