使用awk从LDIF创建postfix别名文件

时间:2013-08-03 18:51:33

标签: awk postfix-mta ldif

我想从ldapsearch的LDIF输出创建一个Postfix别名文件。

LDIF文件包含大约10,000个用户的记录。每个用户至少有一个proxyAddresses属性条目。我需要创建一个与满足以下条件的每个proxyAddress相对应的别名。创建的别名必须指向sAMAccountName@other.domain。

  • 类型为SMTP或smtp(不区分大小写)
  • 完全 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的解决方案,但其他方法也是可以接受的。以下是对我来说最重要的品质:

  1. 简单易读。自我记录比单行更好。
  2. 高效。这将被使用数千次。
  3. 习语。如果它不影响前两个目标,那么“以awk方式”这样做会很好。
  4. 我尝试了什么

    我已经设法开始这个,但我很难理解awk的细节。

    • 我尝试使用csplit为LDIF输出中的每条记录创建单独的文件,但这似乎很浪费,因为我最后只想要一个文件。
    • 我尝试在awk中设置RS=""以获取完整记录而不是单独的行,但后来我不知道从那里去哪里。
    • 我尝试使用awk将大LIDF文件拆分为每个记录的单独文件,然后使用另一个shell脚本处理这些文件,但这看起来很浪费。

2 个答案:

答案 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()}