Udit Gupta
Udit Gupta

Reputation: 3272

Extract last and second last strings of a file in shell variables

Although it is looking similar to my previous post but here purpose is different.

udit@udit-Dabba ~/ah $ cat decrypt.txt
60 00 00 00 00 17 3a 20  00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 01  00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 02  *00 00 e0 f9 6a 61 61 6e
65 6b 61 68 61 6e 67 61  79 65 77 6f 64 69 6e* 00
00 00 03 29 

I want to extract last string of the file (here it is 29) in a shell varaible

I tried this ...

size=`wc -w encrypt.txt`

awk -v size=$size 'BEGIN {RS=" ";ORS=" ";}' {if (NR>size-1 &&
                                         NR < size+1)print $0}' decrypt.txt

Output : 29

But when I changed the file slightly ..

  udit@udit-Dabba ~/ah $ cat decrypt.txt
  60 00 00 00 00 17 3a 20  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 01  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 02  *00 00 e0 f9 6a 61 61 6e
  65 6b 61 68 61 6e 67 61  79 65 77 6f 64 69 6e* 00
  65 6b 61 68 61 6e 67 61  00 00 03 29 

Output : 03

Why there is discrepency between the results ??

I am new to awk and shell features so I am not sure whether it is a right way to do so or not ???

I think there should be some variation of grep,sed,awk or any other linux command which may solve my problem but I am not aware of it.

Please guide me for this.

Thanx in advance.

Purpose :

Make two variables in a shell script which should store last and second last strings of an input file.

Limitation :

Every input file contains a blank line at the end of file.

(Like in above mentioned file , after the file contents there would be one more blank line just like hitting ENTER key and that can not be changed because it is being generated through a C program at run time.)

Upvotes: 1

Views: 3537

Answers (6)

Dignesh P R
Dignesh P R

Reputation: 337

If you got 'rev' utility installed below one would be handy. Presuming that space is the delimiter.

rev <file>|cut -f1,2|rev

Upvotes: 0

uzsolt
uzsolt

Reputation: 6027

grep -v "^$" file | tr " " "\n" | tail -n 2

Maybe the grep-part isn't perfect and maybe should change.

Edit

tr -s " " "\n" < file | tail -n 2

is better solution - see Gordon Davisson's comment.

Upvotes: 2

potong
potong

Reputation: 58371

Here's a tr/sed solution:

answers=$(tr -d '\n' <input_file | sed -r 's/.*(\S\S)\s*(\S\S)\s*$/\1 \2/')
echo "Last = ${answers#???} Penultimate = ${answers%???}"

Sed only:

answers=$(sed -r '1{h;d};H;${x;y/\n/ /;s/.*(\S\S)\s*(\S\S)\s*$/\1 \2/p};d' input_file)
echo "Last = ${answers#???} Penultimate = ${answers%???}"

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246764

If you consider the record separator to be space or newline, then you just need to keep the last 2 records.

awk -v 'RS=[ \n]+' '{prev2 = prev1; prev1 = $0} END {print prev2, prev1}' filename

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753605

To get the last field:

awk '{ if (NF > 0) { last = $NF } } END { print last }' "$@"

The second last field is trickier for the case where there is just one field on the last line (so you need the last field from the line before).

awk '{ if (NF > 0)
       {
           if (NF == 1) { lastbut1 = last; last = $1; }
           else { lastbut1 = $(NF-1); last = $NF; }
       }
     }
     END { print lastbut1 " " last; }' "$@"

This produces a blank and the last value if the file contains but one value. It produces just a blank if there are no values at all.

Upvotes: 1

Michael Krelin - hacker
Michael Krelin - hacker

Reputation: 143071

FIRST="$(head -n 1 file)"
LAST="$(tail -n 1 file)"
LASTBUTONE="$(tail -n 2 file | head -n 1)"

naturally, you can cut off the last field in a variety of ways:

echo "$ONEOFTHOSE" | gawk '{print $(NF)}'
echo "$ONEOFTHOSE" | sed -e 's/^.*[[:space:]]//'

Upvotes: 0

Related Questions