我从ldapsearch的输出中获得了一些数据,如下所示:
> echo "$OUTPUT"
sn: name1
uid: uname1
mail: [email protected]
roomNumber: e2
sn: name2
uid: uname2
mail: [email protected]
roomNumber: e2
sn: name3
uid: uname3
roomNumber: e2
sn: name4
uid: uname4
mail: [email protected]
roomNumber: e2
我正在使用awk将每个用户处理为一行,因此最终会像这样:
name1|uname1|[email protected]|e2
name2|uname2|[email protected]|e2
name3|uname3||e2
name4|uname4|[email protected]|e2
麻烦的是我下面的代码无法处理丢失的邮件属性,因此它重用了前一个用户的变量,看起来像这样:
name1|uname1|[email protected]|e2
name2|uname2|[email protected]|e2
name3|uname3|[email protected]|e2
name4|uname4|[email protected]|e2
使用的awk命令是:
echo "$OUTPUT" | awk -v OFS='|' '{split($0,a,": ")} \
/^sn:/{sn=a[2]} \
/^uid:/{uid=a[2]} \
/^mail:/{mail=a[2]} \
/^roomNumber:/{room=a[2]; print sn, uid, mail, room}'
请问有没有一种方法可以处理上面示例中的邮件之类的缺少属性?
感谢。
只需在打印后将vars设置为空字符串:
$ awk -v OFS='|' '{split($0,a,": ")}
/^sn:/{sn=a[2]}
/^uid:/{uid=a[2]}
/^mail:/{mail=a[2]}
/^roomNumber:/{room=a[2]; print sn, uid, mail, room; sn=uid=mail=room=""}' file
name1|uname1|[email protected]|e2
name2|uname2|[email protected]|e2
name3|uname3||e2
name4|uname4|[email protected]|e2
您能不能尝试以下操作。
awk '
BEGIN{
OFS="|"
}
!NF{
print name,uid,mail,room
name=uid=mail=room=""
}
/sn/{
name=$2
next
}
/uid/{
uid=$2
next
}
/mail/{
mail=$2
next
}
/roomNumber/{
room=$2
}
END{
if(name){
print name,uid,mail,room
}
}
' Input_file
您注意到,您的输入在记录中的结构非常好。每个记录由一组空白行分隔。您可以使用awk来利用它。
下面的想法是读取具有(key: value
)形式的键/值对的每条多行记录>
sn: name2 uid: uname2 mail: [email protected] roomNumber: e2
我们将告诉awk相应地提取该信息并将其存储在数组
data
中。然后,我们将使用该数组以所需的方式重建数据。如果记录中不存在键,则在请求时它将返回一个空值:
awk 'BEGIN{RS=""; FS="\n"; OFS="|"} { delete data; } { for(i=1;i<=NF;++i) { match(/: +/,$i); key=substr($i,1,RSTART-1); value=substr($i,RSTART+RLENGTH); data[key]=value } } { print data["name"], data["uid"], data["mail"], data["room"] }' file
如果以后要更改任何内容,此方法非常通用且非常灵活。