awk question

2007-12-25 9:37:00

My thanks to everyone (too many to list) who

responded to my "silly" awk syntax question. Below

is the summary:

Original Question:

I'm not too familiar with awk, and I'm just trying to

get the home directory of a given user (to put it in

a shell script)

using awk (or sed... it doesn't matter which).

Anyhow, I'm trying to use split or FS to tell it to

user ":" as the

delimiter, but neither seems to work for me:

#grep oracle /etc/passwd

#oracle:x:301:204::/u01/oracle:/bin/tcsh

user=oracle

homedir=`grep $user /etc/passwd | awk '

      BEGIN {

      split($0, field, ":")

      print field[5]

   }'`

echo "$user (home directory) = $homedir"

# I also tried the following:

# grep $user /etc/passwd | awk '{ FS = ":"; print

$5"\n"}'

Summary:

I made 3 mistakes:

1. The syntax for awk is something like

    reg-expr { commands}

BEGIN is a special regular expression that excutes

it's associated commands BEFORE any input lines are

read.

2. FS needs to be set on the command line as an

arguemnt to awk. (or as one of the commands executed

by the BEGIN section.)

3. It's field 6 not 5... (I'm thinking in C, i.e.

things start from subscript 0! Oh well...)

The following are some of the solutions people

recommended:

OPTION 1: Using getent, you will get the entry line

for the user

no matter if it is a local user, or defined in nis or

nis+ tables.

getent passwd $user | cut -f 6 -d ":"

**********************

OPTION 2: If you preffer using grep, you still can do

it,

but you restrict your search to local users:

grep $user /etc/passwd | cut -f6 -d ":"

***********************

OPTION 3: using awk and getent command

getent passwd $user | awk -F: '{print $6}'

***********************

OPTION 4: Using awk and checking directly in the file

grep $user /etc/passwd | awk -F: '{print $6}'

    or

awk -F: ' /^oracle/ {print $6}' </etc/passwd

    or

grep ^$username: /etc/passwd |awk -F: '{print $5}'

You want the ^ at the front of $username so that it

will match only at the START of a line, and the : at

the end so it

matches the ":" separator. This way it will match

bin: rather than foobin or foobin1 for the username...

    or

nawk -F\: '{print $6}' /etc/passwd

   or

awk -F: '$1 == user {print $6}' user=$user <

/etc/passwd

The -F: tells awk to use ":" as delimiter.

The "user=$user" as last argument imports the shell

variable $user as

awk variable user.

<You could also program in ksh, and just use ~user.>

user=oracle

homedir=`grep $user /etc/passwd | awk '

      BEGIN { FS = ":" }

      { print $5 }'`

echo "$user (home directory) = $homedir"

    or

 grep "^oracle:" /etc/passwd | awk 'BEGIN { FS=":" }

{ print $6 }'

    or

 grep $user /etc/passwd | awk '{FS=":"; print $6}'

---

you must use BEGIN when you try to declare that your

field separator is

:

so this is the complete script that you want

set user=oracle

set homedir=`grep $user /etc/passwd|nawk 'BEGIN

{FS=":"} {print $6}'`

---

both csh and ksh understand ~<uid> (which they expand

to home of <uid>). One way that this will work

transparently with nis is:

homedir=`/bin/csh -fc "echo ~$user"`

---

# grep $user /etc/passwd | nnawk ' BEGIN { FS=":" }

{ print $5 } '

this will print the fifth field of the password file.

where fields (FS) are separated by a colon. you need

to specify the value of FS in the begin section,

otherwise it gets overwritten in each line.

you can also use the -v option to just have one

command instead of two (grep and awk)

awk -vUSR=$user ' BEGIN { FS=":" } { if ($1==USR)

print $5 } '

/etc/passwd

this is fairly well documented in the man page for

nawk.

   Ju

   julienlim@rocketmail.com

_________________________________________________________

DO YOU YAHOO!?

Get your free @yahoo.com address at http://mail.yahoo.com

Comments

Got something to say?

You must be logged in to post a comment.