sarath
sarath

Reputation: 455

shell script : find the last integer number from a file

I have a file called sample.txt and the values inside the files are like this:

Editor's note: the sample lines originally had empty lines between them, but the OP has since confirmed that was accidental.

100
200
300
hiiiii

last value is may be null a string or anything other than number....

How can i get the last integer value from the file using unix scripting. the output i am expecting is 300..

i tried the below command but i am getting only hiiiii from this

value=`cat $working_tmp_dir/sample.txt|tail -3| head -1|cut -f2 -d'='|cut -b 1-8`

Upvotes: 0

Views: 1862

Answers (7)

mklement0
mklement0

Reputation: 437197

Assuming that your integers:

  • start on the first line
  • are all in a single block of contiguous lines

you can use this efficient single-command solution (POSIX-compliant):

awk '/^[0-9]+$/ { n=$0; next } { print n; exit }' sample.txt

Note: Even though karakfa's answer involves an additional utility, tac, his answer will likely be faster with large files whose last number is close to the end of the file.

  • /^[0-9]+$/ matches a line consisting of decimal digits only, i.e., a decimal number (possibly with leading zeros).
  • { n=$0; next } saves that line ($0) in variable n and starts processing of the next line (next; skips the remaining commands in the script).
  • { print n; exit } is therefore first executed for the first line that does not consist of decimal digits only; n, which at that point contains the last decimal number encountered, is printed, and exit terminates processing altogether.

Upvotes: 1

JNevill
JNevill

Reputation: 50019

awk would work well here too:

awk  '{ if ($1 ~ /^[0-9]+$/) lastnumber=$1 } END {print lastnumber}' <yourfile.txt>

awk will go through each line in your file and run it through the script inside the single quotes here.

The script, in layman's terms says "Test the first field ($1) of the line to see if it matches this regex, which is looking for a string that is only numeric. If it find a match, then store that match in the variable lastnumber. As awk moves down the file, it changes lastnumber as it finds fully numeric strings in the first field. When it is done (END) processing the file, it prints the value stored in the lastnumber variable.

That being said, if your system supports tac, I would recommend @karakfa's answer as that is going to be more efficient for larger files.

I would also highly recommend to read @mklement0's excellent answer as it uses this same logic, but applies to the entire line of the file and is a much more concise script. Their explanation is very well put together also.

Upvotes: 2

anubhava
anubhava

Reputation: 784998

You can use GNU grep command with -P (PCRE) with -z option that reads whole file at once:

grep -oPz '\d+(?=\D*\z)' file

300

Upvotes: 1

karakfa
karakfa

Reputation: 67467

another alternative

$ tac file | awk '/^[0-9]+$/{print;exit}'

300

reverse the file, print the first number.

Upvotes: 2

Bjorn Munch
Bjorn Munch

Reputation: 496

Another alternative

grep -x '[0-9 ]*' hi.txt | tail -1

(I decided to also allow spaces)

Upvotes: 0

slugo
slugo

Reputation: 1039

This will match the numbers in the file and print the last one.

grep -o "[0-9]*" sample.txt | tail -n 1

Upvotes: 0

Mircea
Mircea

Reputation: 10566

grep  -Eo '^[0-9]+$' hi.txt | tail -1

where hi.txt is your file

Upvotes: 2

Related Questions