Assigning nawk output to variables

I do a lot of command line scripting to capture data from files or other command output. I've checked in a number of Unix and scripting books but for the life of me I can't find out how to asign field data from nawk output into variables that I can manipulate later. For example, reading a two column file like /etc/hosts:

cat /etc/hosts | nawk '{print $1 "\t" $2}'

How can I get $1 and $2 into variables like $IP and $NAME?

many ways.....

#!/bin/ksh

IP='1.1.1.1'
NAME='foo'

echo "BEFORE: IP->[${IP}] NAME->[${NAME}]"

echo '2.2.2.2 bar' | eval $(nawk '{printf("IP=%s NAME=%s\n", $1, $2)}')

echo "AFTER: IP->[${IP}] NAME->[${NAME}]"

vgersh99,

Hmm, can't quite grasp the technique. I tried the following:

cat hosts | eval $(nawk '{printf("IP=%s NAME=%s\n", $1, $2)}') | echo $IP $NAME
AZPHNX-E-3600-02 ( got back 1/2 line of a 3500 line file)

cat hosts | eval $(nawk '{printf("IP=%s NAME=%s\n", $1, $2)}') | echo [${IP}] [${NAME}]
[] [AZPHNX-E-3600-02] (same results)

>for i in `cat hosts`
> do
> eval $(nawk '{printf("IP=%s NAME=%s\n", $1, $2)}')
> echo $IP $NAME
> done
^C (no output!)

strange. what's your 'hosts' file look like?

there's no input for this 'nawk' invokation.
you don't need awk anyway....

while read IP NAME junk
do
   echo "[${IP}] [${NAME}]"
done < /etc/hosts

Though maybe not so pertinent to your particular problem at hand, but I think the basic principle you need to grasp here is that of command subsitution, implemented in the Bourne shell with backtics, `command`, or with newer Bourne derivatives also as $(command). Command subsitution replaces the output of the command at that point in the script. Thus if you want to save the output of a command as a shell variable for later use:

MY_VAR=$(my_command)

The <my_command> can be as fancy as you want -- it can be a huge pipeline of whatever.

If you want to save more than one variable from the output of a command, one option is to use MY_VAR=$(my_command), and then parse out $MY_VAR into its components, saving each in its own variable.
But maybe an easier method is to use the read builtin. Now, shell builtins are usually run as the same process as the invoking shell, and so variable assignments done by builtins will have effect in the current shell and its environment. However, in most Bourne-like shells, all commands in a pipeline will be executed as a subprocess -- even builtins and functions -- and so variable assignments done in pipelines will have no effect in the current shell's environment. (External commands are always run as subprocesses.)
I say this because it is tempting to try the following to save variable(s) from the output of a command:

mycomm | read VAR [VAR2]
# for example:
echo George Bush | read FIRST LAST
echo $FIRST
<nothing>
echo $LAST
<nothing>

Because read, though a shell builtin, is here part of a pipeline, and not a simple command, it will be executed as a subprocess. So VAR1 and VAR2 will still be undefined (or unchanged) in the current shell.
To get around this problem, the AT&T Korn shell -- but not pdksh, nor bash -- has been made different in this regard, because if a shell builtin or function is the last element of a pipeline, it will still be run in the current shell process, and so variable assignments will take effect in the current shell. Thus the above example will work in the AT&T ksh.
But in most other shells, one trick to get around this is by using here documents--rather than a pipe--to send the command's output into the standard input of read. For you can do command subsitution in a here doc. For example:

read FIRST LAST <<EOF
$(echo George Bush)
EOF
echo $FIRST
George
echo $LAST
Bush
# or using your original code--though it does not fit my discussion, for you
# probably need iteration if you want to get all pairs from /etc/hosts;
# but as a matter of principle of how to assign vars from command output
read IP NAME <<EOF
$(cat /etc/hosts | nawk '{print $1 "\t" $2}')
EOF

Note that bash and ksh93 (not ksh88) have a <<< name operator -- a "here string", really a one-line here document -- where name gets variable/command/arithmetic expanded. Thus in bash and ksh93 (maybe only some versions of ksh93) you can do:

read FIRST LAST <<< $(echo George Bush)

But it is sometimes useful to pipe stuff into read to set variables, but only if you want to use those variables transiently right there in that block of code, and not later in your script. For example, you can still do:

mycomm | while read MY_VAR; do
  other_commands_using $MY_VAR
done

I.e., $MY_VAR will be available in the while read compound statement, and you can use it in there. But it won't have effect in the current shell outside of this while read statement.
Note also that--in this regard--pipelines are not the same as file redirections, and so the read builtin in "read HOSTNAME < /etc/hostname" is NOT run in a subprocess, and $HOSTNAME will be accessible in the current shell. (We see this in the /etc/hosts example of this thread.) This is also the reason why the here document method outlined above works.

...and by the way, if you do want to set a variable with a value from a subprocess, check out the thread at Getting value of variable set in subprocess script

In Korn Shell you can use the set command:

spd01: /home/obd/tst > set $(echo george bush)
spd01: /home/obd/tst > print $1
george
spd01: /home/obd/tst > print $2
bush
spd01: /home/obd/tst >

after this
my_var1=$1
my_var2=$2

or use 'shift'.