Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: extract (percent) number of variable length from a string

I want to write a little progress bar using a bash script.

To generate the progress bar I have to extract the progress from a log file.

The content of such a file (here run.log) looks like this:

Time to finish 2d 15h, 42.5% completed, time steps left 231856

I'm now intersted to isolate the 42.5%. The problem is now that the length of this digit is variable as well as the position of the number (e.g. 'time to finish' might content only one number like 23h or 59min).

I tried it over the position via

echo "$(tail -1 run.log | awk '{print $6}'| sed -e 's/[%]//g')"

which fails for short 'Time to finish' as well as via the %-sign

echo "$(tail -1 run.log | egrep -o '[0-9][0-9].[0-9]%')"

Here is works only for digits >= 10%.

Any solution for a more variable nuumber extraction?

======================================================

Update: Here is now the full script for the progress bar:

#!/bin/bash

# extract % complete from run.log
perc="$(tail -1 run.log | grep -o '[^ ]*%')"

# convert perc to int
pint="${perc/.*}"

# number of # to plot
nums="$(echo "$pint /2" | bc)"

# output
echo -e ""
echo -e "   completed: $perc"
echo -ne "   "
for i in $(seq $nums); do echo -n '#'; done
echo -e ""
echo -e "  |----.----|----.----|----.----|----.----|----.----|"
echo -e "  0%       20%       40%       60%       80%       100%"
echo -e ""
tail -1 run.log
echo -e ""

Thanks for your help, guys!

like image 625
Stephan Avatar asked Jan 30 '13 13:01

Stephan


2 Answers

based on your example

grep -o '[^ ]*%'

should give what you want.

like image 193
Kent Avatar answered Sep 20 '22 12:09

Kent


You can extract % from below command:

tail -n 1 run.log | grep -o -P '[0-9]*(\.[0-9]*)?(?=%)'

Explanation:

grep options:
-o : Print only matching string.
-P : Use perl style regex

regex parts:
[0-9]* : Match any number, repeated any number of times.
(\.[0-9]*)? : Match decimal point, followed by any number of digits. 
              ? at the end of it => optional. (this is to take care of numbers without fraction part.)
(?=%)  :The regex before this must be followed by a % sign. (search for "positive look-ahead" for more details.)
like image 25
anishsane Avatar answered Sep 22 '22 12:09

anishsane