使用awk从LDIF创建后缀别名文件

使用awk从LDIF创建后缀别名文件,awk,postfix-mta,ldif,Awk,Postfix Mta,Ldif,我想从ldapsearch的LDIF输出创建后缀别名文件 LDIF文件包含大约10000个用户的记录。每个用户至少有一个proxyAddresses属性条目。我需要创建一个与满足以下条件的每个代理地址对应的别名。创建的别名必须指向sAMAccountName@other.domain. 类型为SMTP或SMTP(不区分大小写) 域名正是contoso.com 我不确定LDIF文件中的属性顺序是否一致。我想我不能假设sAMAccountName总是最后出现 示例输入文件 dn: CN=John

我想从
ldapsearch
的LDIF输出创建后缀别名文件

LDIF文件包含大约10000个用户的记录。每个用户至少有一个
proxyAddresses
属性条目。我需要创建一个与满足以下条件的每个代理地址对应的别名。创建的别名必须指向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
示例输出文件

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的方式”就很好了
  • 我尝试过的

    我已经设法在这方面做了一个开始,但我正在努力理解awk的更好之处

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

      • 这里有一个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"
                }
            }
        }
        
        $cat ldif.awk
        开始{
        RS=“\n\n”#记录分隔符:空行
        FS=“\n”#字段分隔符:换行符
        }
        #对于每条记录:在字段中循环两次
        {
        #循环#1标识sAMAccountName
        
        对于(i=1;i,这里有一种使用标准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要求。