我想从ldapsearch
的LDIF输出创建一个Postfix别名文件。
LDIF文件包含大约10,000个用户的记录。每个用户至少有一个proxyAddresses
属性条目。我需要创建一个与满足以下条件的每个proxyAddress相对应的别名。创建的别名必须指向sAMAccountName@other.domain。
contoso.com
我不确定LDIF文件中的属性排序是否一致。我不认为我可以假设sAMAccountName将始终显示在最后。
示例输入文件
dn: CN=John Smith,OU=Users,DC=contoso,DC=com
proxyAddresses: SMTP:smith@contoso.com
proxyAddresses: smtp:John.Smith@contoso.com
proxyAddresses: smtp:jsmith@elsewhere.com
proxyAddresses: MS:ORG/ORGEXCH/JOHNSMITH
sAMAccountName: smith
dn: CN=Tom Frank,OU=Users,DC=contoso,DC=com
sAMAccountName: frank
proxyAddresses: SMTP:frank@contoso.com
proxyAddresses: smtp:Tom.Frank@contoso.com
proxyAddresses: smtp:frank@elsewhere.com
proxyAddresses: MS:ORG/ORGEXCH/TOMFRANK
示例输出文件
smith: smith@other.domain
John.Smith: smith@other.domain
frank: frank@other.domain
Tom.Frank: frank@other.domain
理想的解决方案
我希望看到使用awk
的解决方案,但其他方法也是可以接受的。以下是对我来说最重要的品质:
我尝试了什么
我已经设法开始这个,但我很难理解awk的细节。
RS=""
以获取完整记录而不是单独的行,但后来我不知道从那里去哪里。答案 0 :(得分:1)
这是一个gawk脚本,你可以像这样运行:gawk -f ldif.awk yourfile.ldif
请注意:“RS”的多字符值是gawk扩展名。
$ cat ldif.awk
BEGIN {
RS = "\n\n" # Record separator: empty line
FS = "\n" # Field separator: newline
}
# For each record: loop twice through fields
{
# Loop #1 identifies the sAMAccountName
for (i = 1; i <= NF; i++) {
if ($i ~ /^sAMAccountName: /) {
sAN = substr($i, 17)
break
}
}
# Loop #2 prints output lines
for (i = 1; i <= NF; i++) {
if (tolower($i) ~ /smtp:.*@contoso.com$/) {
split($i, n, ":|@")
print n[3] ": " sAN "@other.domain"
}
}
}
答案 1 :(得分:1)
这是使用标准awk的方法。
# Display the postfix alias(es) for the previous user (if any)
function dump() {
for(i in id) printf("%s: %s@other.domain\n",id[i],an);
delete id;
}
# store all email names for that user in the id array
/^proxyAddresses:.[Ss][Mm][Tt][Pp]:.*@contoso.com/ {gsub(/^.*:/,"");gsub(/@.*$/,"");id[i++]=$0}
# store the account name
/^sAMAccountName:/ {an=$2};
# When a new record is found, process the previous one
/^dn:/ {dump()}
# Process the last record
END {dump()}