1

I'm creating a simple awk script to parse AIX's lsuser -f ALL output and return information in one line. A sample of the output is something like this.

root:
    id=0
    pgrp=something
    groups=something
    home=/
    shell=/usr/bin/csh
    auditclasses=general
    login=true
    su=false

Here is my code so far:-

$1 ~ /[^=]:[ ]*$/ {sub(/:/,"",$1);printf $1" ";FS="="}
$1 ~ /login/         {printf $2" "}
$1 ~ /su/     {printf $2" "}
$1 ~ /account_locked/         {printf $2" "}
$1 ~ /time_last_login/     {print $2}

The script does not work well with fields that does not exist for certain ID such as time_last_login because some user may not have logged in before. Example as per below.

root something ALL false 1360813178
**daemon staff ALL true sysadm1 something ALL false 1352015794**
sysadm2 staff ALL true 1352015794

sysadm1 line should be in a new line. How do I fix this?

1

You could add a variable e.g. user when you get to the user: line. Thus if it is set print a newline before user name, else not, and skip print of newline under time_last_login.

If one or more fields could be missing you would probably use an array and print after each iteration of user and add an END{} for last.

This way you can print e.g. N/A for missing fields.

Alternatively use an array to specify which fields you want to print.

Example (with both):

function prnt_user_data(arr, prnt) {
    printf("\nAlternative 1:\n")
    for (p in prnt) {
        printf("%s ", prnt[p] in arr ? arr[prnt[p]] : "N/A")
    }
    printf("\nAlternative 2:\n")
    printf(\
    "%s %s %s %s\n",
    "user"            in arr ? arr["user"] : "N/A",
    "su"              in arr ? arr["su"] : "N/A",
    "account_locked"  in arr ? arr["account_locked"] : "N/A",
    "time_last_login" in arr ? arr["time_last_login"] : "N/A" \
    );
    delete arr;
}

BEGIN {
    FS="=|[ \t]*"
    prnt_flds["01"]="user";
    prnt_flds["02"]="su";
    prnt_flds["03"]="account_locked";
    prnt_flds["04"]="time_last_login";
}
NF == 0 {next}
NF == 3 {
    user_data[$2]=$3;
}
NF == 1 && /:[ ]*$/{
    if("user" in user_data)
        prnt_user_data(user_data, prnt_flds)
    user_data["user"]=substr($1, 1, length($1) - 1);
}
END {
    if("user" in user_data)
        prnt_user_data(user_data, prnt_flds)
}
1
  • Thanks Sukminder for the explanation. I understand better now. May 5 '13 at 21:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.