【问题标题】:Create postfix aliases file from LDIF using awk使用 awk 从 LDIF 创建后缀别名文件
【发布时间】:2013-08-07 16:19:58
【问题描述】:

我想从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 方式”进行操作会很好。

我的尝试

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

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

【问题讨论】:

    标签: awk postfix-mta ldif


    【解决方案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"
            }
        }
    }
    

    【讨论】:

    • 谢谢,这正是我需要的结果!
    【解决方案2】:

    这是一种使用标准 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()}
    

    【讨论】:

    • 这几乎对我有用,但我需要它来跳过所有非 SMTP 类型的地址。不过,我喜欢这个非常简洁的方式。
    • 代码已修复,我忽略了 smtp 要求。
    猜你喜欢
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2011-04-11
    相关资源
    最近更新 更多