Return the first number found greater than the provided input number (13 digits) This script converts the numbers to be at least 13 characters long (for UNIX_MS strings). For use with timestamps, I'm having issues with it being very slow. I wanted an alternative to grepping for one specific UNIX_MS timestamp and not finding it and then having to grep multiple more times.

For the output I wanted the line number in the file (for slicing) as well as the original line (to confirm/inspect).

I'm very specifically looking for optimizations as I'd like this to be as-close-to-as-fast as grepping a single timestamp.

Usage: ./script.sh file UNIX_MS

#! /bin/bash
# return the first number found that's greater than the provided input number
res=
linenum=
count=0
returnline=             # hold onto the line for return
tocheck=$2
tocheck=$(($tocheck*(10**(( ${#tocheck} - 13) * -1))))
inseconds=$(($tocheck/1000))
date=$(date -r $inseconds)
echo "Looking for first timestamp -ge to $date.."
while read line;
  do
    count=$(($count + 1))
    timearray=$(grep -o -E "^(.*?)([0-9]{10,13})?" &lt;&lt;&lt; $line)
    if [ -z "$timearray" ]; then
    echo "PROBLEM"
        echo "grep -o -E '^(.*?)([0-9]{10,13})?' &lt;&lt;&lt; $line"
        exit 1
    fi
    timestamp=$(sed -Ee "s/[0-9]+\://" &lt;&lt;&lt; $timearray)
# normalize timestamp to be 13 digits
    if [ "${#timestamp}" -lt "13" ]; then
        mult=$((10**(( ${#timestamp} - 13) * -1)))
        timestamp=$(($timestamp * $mult))
    fi
    echo "$timestamp &gt;= $tocheck?"
    linenum=$([ "$timestamp" -ge "$tocheck" ] &amp;&amp; echo $count)
    if [ -z "$linenum" ]; then
        :;
    else
        returnline=$line 
    break;
    fi
done &lt; $1
echo "$linenum:$returnline"
echo ""
I'm having issues with it being very slow. 


What makes your script code slow is that you're reading in the file yourself with the while loop, and apply grep to each single input line, instead of passing grep the file itself and let it just do it's job.

No matter what you want to search for with grep, you should always first pass your input to it with a single call, and inspect the results afterwards.


  For the output I wanted the line number in the file (for slicing) as well as the original line (to confirm/inspect).


grep already has this feature intrinsically (at least as it says from this documentation):


  
    -n, --line-number
           Prefix each line of output with the line number within its input file.
  


you simply can do what you want using this option.

Thus you can get rid of your while loop and count variable to determine the line number yourself.