awk删除不需要的记录,并按特定顺序将多行字段合并到一行记录中

时间:2014-01-07 11:06:37

标签: replace awk ldap getline

我有一个输出文件,我正在尝试为我们的审计团队处理格式化的csv。

我以为我掌握了这个,直到我偶然发现输出中的坏数据。因此,我希望能够使用awk来处理这个问题。

我的输出文件示例

Enter password ==>
o=hoster

ou=people,o=hoster

ou=components,o=hoster

ou=websphere,ou=components,o=hoster

cn=joe-bloggs,ou=appserver,ou=components,o=hoster
cn=joe
sn=bloggs
cn=S01234565
uid=bloggsj

cn=john-blain,ou=appserver,ou=components,o=hoster
cn=john
uid=blainj
sn=blain

cn=andy-peters,ou=appserver,ou=components,o=hoster
cn=andy
sn=peters
uid=petersa
cn=E09876543

我希望处理后的输出

joe,bloggs,s01234565;uid=bloggsj,cn=joe-bloggs,ou=appserver,ou=components,o=hoster
john,blain;uid=blainj;cn=john-blain,ou=appserver,ou=components,o=hoster
andy,peters,E09876543;uid=E09876543;cn=andy-peters,ou=appserver,ou=components,o=hoster

如你所见:

  1. 我们总是有一个包含o = hoster
  2. 的cn =变量
  3. uid可以有任何价值
  4. 我们可能有多个cn =变量而没有o = hoster
  5. 我已经实现了以下目标:

    cat output | awk '!/^o.*/ && !/^Enter.*/{print}' | awk '{getline a; getline b; getline c; getline d;  print  $0,a,b,c,d}' | awk -v srch1="cn=" -v repl1="" -v srch2="sn=" -v repl2="" '{ sub(srch1,repl1,$2); sub(srch2,repl2,$3); print $4";"$2" "$3";"$1 }'
    

    使用awk非常感谢任何指针或指导。或者我应该放弃并只使用古老的long winded方法来处理文件?

4 个答案:

答案 0 :(得分:2)

您可以尝试关注 awk 代码

$ cat file
Enter password ==>
o=hoster

ou=people,o=hoster

ou=components,o=hoster

ou=websphere,ou=components,o=hoster

cn=joe-bloggs,ou=appserver,ou=components,o=hoster
cn=joe
sn=bloggs
cn=S01234565
uid=bloggsj

cn=john-blain,ou=appserver,ou=components,o=hoster
cn=john
uid=blainj
sn=blain

cn=andy-peters,ou=appserver,ou=components,o=hoster
cn=andy
sn=peters
uid=petersa
cn=E09876543

Awk代码:

awk      '
   function out(){
                   print s,u,last
                   i=0; s=""
                 }
        /^cn/,!NF{ 
                   ++i      
                   last = i == 1 ? $0 : last
                   s = i>1 && !/uid/ && NF ? s ? s "," $NF : $NF : s
                   u = /uid/ ? $0 : u
                 }
         i && !NF{
                   out()
                 }
              END{
                   out()
                 }
          ' FS="=" OFS=";" file

所得

joe,bloggs,S01234565;uid=bloggsj;cn=joe-bloggs,ou=appserver,ou=components,o=hoster
john,blain;uid=blainj;cn=john-blain,ou=appserver,ou=components,o=hoster
andy,peters,E09876543;uid=petersa;cn=andy-peters,ou=appserver,ou=components,o=hoster

如果您想在Solaris/SunOS系统上尝试此操作,请将awk更改为/usr/xpg4/bin/awk/usr/xpg6/bin/awknawk

答案 1 :(得分:1)

awk脚本适用于您的样本并生成示例输出:

BEGIN { delete cn[0]; OFS = ";" }
function print_info() {
    if (length(cn)) {
        names = cn[1] "," sn
        for (i=2; i <= length(cn); ++i) names = names "," cn[i]
        print names, uid, dn
        delete cn
    }
}
/^cn=/ {
    if ($0 ~ /o=hoster/) dn = $0
    else {
        cn[length(cn)+1] = substr($0, index($0, "=") + 1)
        uid = $0; sub("cn", "uid", uid)
    }
}
/^sn=/ { sn = substr($0, index($0, "=") + 1) }
/^uid=/ { uid = $0 }
/^$/ { print_info() }
END { print_info() }

这应该可以帮助您入门。

答案 2 :(得分:1)

awk '$1 ~ /^cn/ {
  for (i = 2; i <= NF; i++) {
    if ($i ~ /^uid/) {
    u = $i 
    continue
    }
    sub(/^[^=]*=/, x, $i)
    r = length(r) ? r OFS $i : $i
    }
    print r, u, $1 
    r = u = x
  }' OFS=, RS= infile

我假设您的示例输出中存在错误:在3d记录中, uid 应该是 petersa 而不是 E09876543 。< / p>

答案 3 :(得分:0)

您可能需要查看一些“已经存在且已完成”的解决方案来完成任务。

例如,

Apache Directory Studio将执行LDAP查询并以CSV或XLS格式保存文件。

-Jim