Reputation: 733
I have a log which every minute receives the following data:
ID: Unit3443 IP: 192.168.1.1 MAC: 00:20:c0:04:e8:ab
ID: Unit2222 IP: 192.168.2.2 MAC: 00:40:c0:05:e8:bc
I grab the last line with tail -1 /File
Is it possible to assign both of those entries to variable in one swoop? Currently I have
UnitID=`tail -1 $File|awk '{print $1}'`
UnitIP=`tail -1 $File|awk '{print $2}'`
This works but it requires the file to be read twice and my concern is during the second read the output of tail -1 will no longer be the same.
Is it possible to assign both these variables in one read of the line?
Upvotes: 1
Views: 743
Reputation: 207660
You could do this:
read UnitID UnitIP < <(awk 'END{print $2, $4}' file)
Test Result
echo $UnitID
Unit2222
echo $UnitIP
192.168.2.2
As @EdMorton kindly points out in the comments, not all awk
variants retain the $0..$NF variables into the END
section, so the following is hopefully more widely applicable:
read UnitID UnitIP < <(awk '{a=$2; b=$4} END{print a,b}' file)
Upvotes: 1
Reputation: 7509
You can use the read
builtin instead of awk
:
IFS=$' \t' read -r Unit{ID,IP} _ <<< "$(tail -1 "$file")"
$ declare -p Unit{ID,IP}
declare -- UnitID="Unit2222"
declare -- UnitIP="192.168.2.2"
Or if your input file really follows the updated format (I don't see how your original code could work):
IFS=$' \t' read -r _ UnitID _ UnitIP _ <<< "$(tail -1 "$file")"
Upvotes: 1
Reputation: 203975
arr=( $(tail -1 "$file" | awk '{print $1, $2}') )
UnitID=${arr[0]}
UnitIP=${arr[1]}
or:
id=0
ip=1
unit=( $(tail -1 "$file" | awk '{print $1, $2}') )
echo "${unit[id]}"
echo "${unit[ip]}"
or:
line=$(tail -1 "$file" | awk '{print $1, $2}')
UnitID="${line% *}"
UnitIP="${line#* }"
Upvotes: 2
Reputation: 301
Another alternative instead of using read
suggested by @PesaThe would be to do the tail
in one go and use the result twice in order to avoid problems when the file changes between tail
s.
LINE="$(tail -1 "$File")"
UnitID="$(echo "$LINE" | awk '{print $1}')"
UnitIP="$(echo "$LINE" | awk '{print $2}')"
Note: I've also changed the sample to use $()
instead of backticks - works the same way, but easier to get right.
Upvotes: 1