私はAIXのlsuser -f ALL
出力を解析し、情報を1行で返す単純なawkスクリプトを作成しています。サンプル出力は次のとおりです。
root:
id=0
pgrp=something
groups=something
home=/
shell=/usr/bin/csh
auditclasses=general
login=true
su=false
これは私のコードです。
$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}
time_last_login
たとえば、一部のユーザーが以前にログインしていない可能性があるため、一部のIDが存在しないフィールドではスクリプトが正しく機能しません。例は次のとおりです。
root something ALL false 1360813178
**daemon staff ALL true sysadm1 something ALL false 1352015794**
sysadm2 staff ALL true 1352015794
sysadm1ラインは新しいラインに置き換える必要があります。どうすれば解決できますか?
答え1
user
たとえば、その行に達すると変数を追加できますuser:
。もしそうならはいユーザー名の前に印刷する改行文字を設定します。それ以外の場合は印刷されず、次の改行文字はスキップされますtime_last_login
。
1つ以上のフィールドがない場合は、配列を使用してユーザーが繰り返すたびに印刷して、END{}
最後に1つを追加できます。
たとえば、この方法N/A
で欠落しているフィールドを印刷できます。
または、配列を使用して印刷するフィールドを指定します。
はい(両方):
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)
}