LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   awk syntax error and question? (https://www.linuxquestions.org/questions/linux-general-1/awk-syntax-error-and-question-4175441172/)

Spazztic_Killer 12-12-2012 12:41 PM

awk syntax error and question?
 
what I am trying to do is make a script to add users to the system.
I am reading in 2 varibaled by "read -p "Enter Username: " UN . And then like "read -p "Enter Fullname of User: " FN
And my awk looks like
`awk -F':' '$1 ~ "/\<'$UN'\>/" { print $0 }' /etc/passwd`

I am putting in checks to either fail out if user exists or printf to null and continue.

What I want or would like is for example i run it it will ask me and i enter for 1st Bob, 2nd Bob Jones. The second one i have a space in it, But the awk there delimits by a ':".. But I have tried Bob:Jones also put it prints Bob:Jones Because i have setup to echo the names and exit to make sure thins are working before it moves on to the rest of the script i have already written.

I have also thought of reading in the 2 varibales has $1, and $2 ??

Any help would be appreciated thank you very much.

colucix 12-12-2012 12:54 PM

I'm not sure about what the problem is. Something like
Code:

awk -F: '$5 ~ /'"$FN"'/' /etc/passwd
should work. Anyway, awk is not necessary if you want only to check for the existence of a full user name in /etc/passwd. Using grep:
Code:

grep ":$FN:" /etc/passwd
should serve the purpose. If not, please can you elaborate and show the current version of your script (using CODE tags to improve readability and preserve spacing)?

Spazztic_Killer 12-12-2012 01:18 PM

ok thanks for the quick reply. Ok here it goes this is the top part of the code that i am working on and have it to exit out. Has you'll find out below i have muiltiple different ways in there that i was testing and messing around with to try and get it to work and error out correctly if needed.

set -x
if [ "$?" -eq 0 ]
then
read -p "Enter your UserName: " UN
read -p "Enter your FullName: " FN
if [ "$?" -eq 0 ]
then
awk -F':' '$1 ~ /\<'$UN'\>/ { print $0 }' /etc/passwd
#grep "$UN" /etc/passwd
if [ "$?" -eq 1 ]
then
printf "User Doesnt Exist%s\n"
#`printf > /dev/null`
else
echo "User Does Exist:: WARN:"
fi
fi
fi
exit

Its not the cleanest, And i was just writing in some garbage to tell the different parts were spitting out errors.

Spazztic_Killer 12-12-2012 01:22 PM

When i do the run it awk always seem to spit out a 0 even when user "Bob" didnt exist., I guess i would like to use awk maybe in less grep works better?

Did doesnt seem to work, my name is Jonathan, so if i type in "than". It will still display jonathan in the /etc/passwd file thats ofcourse is not what i what can grep do this easier?

trey85stang 12-12-2012 02:04 PM

awk isnt going to spit out a 1 just if a regex does not match; you have to tell it to do that.

also, you cant call the variable $UN or $FN from inside an awk script. For this purpose; grep would probably be a better tool. Since a match is a zero and a non match is a 1.

Please use code tags around script to preserve spacing and indentions.

Code:

set -x
if [ "$?" -eq 0 ]
then
  read -p "Enter your UserName: " UN 
  read -p "Enter your FullName: " FN
  if [ "$?" -eq 0 ]
  then
    #untested,  change below
    awk -vUN=$UN-F':' '$1 ~ /\<UN\>/ { print $0 }' /etc/passwd
    #grep "$UN" /etc/passwd
    if [ "$?" -eq 1 ]
    then
      printf "User Doesnt Exist%s\n"
      #`printf > /dev/null`
    else
      echo "User Does Exist:: WARN:"
    fi
  fi
fi
exit

Im not sure about the \<\> or what exactly you are looking for in /etc/passwd... Also, you could simplify the command a bit..

Code:

if mycommand
then
  #do something on success
else
  #do something different on failure
fi

The above is a little easier to read rather then using multiple $? calls... If you need to check more then pass or fail and need specific actions based on the return code then use a case statement... etc.

colucix 12-12-2012 02:41 PM

Yes. As trey85stang stated, awk returns zero if the are not error in the program execution (like syntax errors, divisions by zero and so on). You have to use an exit statement with an argument different than 0 to do otherwise. Example:
Code:

awk -F: '$1 ~ /\<'$UN'\>/{s ? s = 0 : s = 3} END{exit s}' /etc/passwd
should return 3 if the user name is matched, 3 otherwise.

Regarding the partial match of the grep command, it is the reason I used:
Code:

grep ":$FN:" /etc/passwd
in my previous example, with colons around the $FN value. In alternative you can try the -w option to match the whole word:
Code:

grep -w "$FN" /etc/passwd

PTrenholme 12-12-2012 07:29 PM

TO expand on the above comment by the moderator, consider this command list:
Code:

$ grep -0 '^[^ ]' /etc/passwd | sort -n -t: -k3 | cut -d: -f1,3,5 | tr ':' '\t'
root    0      root
bin    1      bin
daemon  2      daemon
adm    3      adm
lp      4      lp
sync    5      sync
shutdown        6      shutdown
halt    7      halt
mail    8      mail
uucp    10      uucp
operator        11      operator
games  12      games
gopher  13      gopher
ftp    14      FTP User
mysql  27      MySQL Server
rpcuser 29      RPC Service User
rpc    32      Rpcbind Daemon
gdm    42
mailnull        47
apache  48      Apache
smmsp  51
vcsa    69      virtual console memory owner
avahi  70      Avahi mDNS/DNS-SD Stack
tcpdump 72
sshd    74      Privilege-separated SSH

The -0 option to the grep command tells it that the lines are null terminated, the search pulls out every user whose user name does not start with a blank (including any with no user name). In your code, you could look for a specific user by grep -0 "^${UN}:".

The sort just sorts the users by their UID, to make the output easier to follow. This is, of course, not necessary for your task.

The cut extracts the user name, UID, and full name from the grep returned lines, and the tr is there to replace the ':' delimiter used in /etc/passwd by a tab character, again just to make the output easier to follow.

<edit>
Oh, this command would set the variable ${full_name} to the full name of the user ${UN}:

full_name=$(grep -0 "^${UN}:" | cut -d: -f3)

and you could test for a missing full_name with a if [ -z "${full_name}" ];then ... or similar construct.

Note that I, as a personal choice, prefer to always use the ${variable_name} form. It prevents confusion and ambiguity.
</edit>

<edit2>
Oops!:redface: I was just lookig at the man grep output (for another option I'd forgotten) and notices that the [-0 option was not listed, and that -z is the preferred way to specify a null as the line terminator. (Apparently -0 is a "hidden" option.

</edit2>

Spazztic_Killer 12-12-2012 08:03 PM

Perfect thanks alot I can take it from there just bit more of an understanding. I'll clean up the code. Thanks again.


All times are GMT -5. The time now is 01:41 AM.