免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2369 | 回复: 9
打印 上一主题 下一主题

根据每行的内容合并多行 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-29 12:10 |只看该作者 |倒序浏览
现在有一些从ldap数据库中拉出来的用户组数据,得把这些数据转化成/etc/group的格式,数据如下
dn: cn=sysadminGrp,ou=Group,dc=auth,dc=asp
cn: sysadminGrp
gidNumber: 642
memberUid: blei
memberUid: xfwu
memberUid: ymxu

dn: cn=asplogoGrp,ou=Group,dc=auth,dc=asp
gidNumber: 648
cn: asplogo
memberUid: amchen
memberUid: tfeng


合并以后的格式为
sysadminGrp:642:blei,xfwu,ymxu
asplogoGrp:648:amchen,tfeng


还请大家给个思路,现在无从下手,因为某些字段的顺序不行(gidNUmber和cn),某一个记录的行数也不固定(memberUid数目不定)

论坛徽章:
0
2 [报告]
发表于 2007-09-29 13:32 |只看该作者
myawk.awk:
  1. BEGIN{
  2.         FS="[:,]";
  3. }

  4. {
  5.         gsub(/[ \t]/,"");
  6.         if($1~/^dn/){
  7.                 split($2,str,/=/)
  8.                 a=str[2];
  9.         }
  10.         if($1~/gidNumber/)b=$2;
  11.         if($1~/^memberUid/){
  12.                 strings[$2]=$2;
  13.         }
  14.         if($1!~/^[a-z]+/){
  15.                 printf("%s:x:%s:",a,b);
  16.                 for(i in strings){printf("%s,",strings[i])};
  17.                 delete strings;
  18.                 printf "\n";
  19.         }
  20. }
复制代码

  1. gawk -f myawk.awk UrDatafile|sed 's/,$//'
复制代码


最后保证UrDatafile最后两行为空行,如果不是可能得不到最后一组的结果..

论坛徽章:
0
3 [报告]
发表于 2007-09-29 13:42 |只看该作者
test.sh

  1. #!/bin/bash
  2. while read line
  3. do
  4.   case $line in
  5.     dn:*)
  6.       CN=${line#*:}
  7.       CN=${CN%%,*}
  8.       CN=${CN#*=}
  9.       ;;
  10.     gidNumber:*)
  11.       GID=${line#*:}
  12.       ;;
  13.     memberUid:*)
  14.       if [ X${memberUid} == X ];then
  15.         memberUid="${line#*:}"
  16.       else
  17.         memberUid="${memberUid},${line#*:}"
  18.       fi
  19.       ;;
  20.     *)
  21.       if [ X$line == X ];then
  22.         echo "${CN}:x:${GID}:${memberUid}"
  23.         CN=
  24.         GID=
  25.         memberUid=
  26.       fi
  27.       ;;
  28.   esac
  29. done
  30. [ X${CN} != X ] && echo "${CN}:x:${GID}:${memberUid}"
复制代码


  1. sed 's/[[:blank:]]//g' 文件 | ./test.sh
复制代码

注:
sed 目的是删除文件中所有的空白符


[ 本帖最后由 springwind426 于 2007-9-29 13:46 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-09-29 13:46 |只看该作者
3楼的强,学习~~

论坛徽章:
0
5 [报告]
发表于 2007-09-29 14:11 |只看该作者
多谢__lxmxn__和springwind426 了,可以了。
还有一个问题问一下springwind426,最后一行是做什么的啊,前面的while循环已经把所有记录都处理完了啊?

论坛徽章:
0
6 [报告]
发表于 2007-09-29 14:30 |只看该作者
如果文件的最后一行不是空行的话,那么,是不会显示最后一个记录的

此时,那些变量中保存着最后一条记录,因此,需要显示出来
[ X${CN} != X ] 是判断$CN是否不为空,如果不为空,表示还有一个记录没有打印,需要打印出来

[ 本帖最后由 springwind426 于 2007-9-29 14:33 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-09-29 15:03 |只看该作者
请问 LZ 以下红色部分不一样,是你的笔误还是原本如此,如果是笔误,程序可以简单许多

dn: cn=asplogoGrp,ou=Group,dc=auth,dc=asp
gidNumber: 648
cn: asplogo
memberUid: amchen
memberUid: tfeng

论坛徽章:
0
8 [报告]
发表于 2007-09-29 15:07 |只看该作者
还是别浪费刚写的吧,我刚才没看清楚红色部分的不同,写了以下程序,不好意思:

awk -F':' '
$1~/dn/ {
    n["cn"] = n["gidNumber"] = n["memberUid"]= "";
    while (getline>0 && NF>1) {
        sub(/[ \t]/, "";
        n[$1] = n[$1] == "" ? $2 : n[$1]","$2;
    }
    printf("%s:%s:%s\n", n["cn"], n["gidNumber"], n["memberUid"]);
}'  inputfile


[ 本帖最后由 seeLnd 于 2007-9-29 16:39 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2007-09-29 15:27 |只看该作者
seeLnd , 不好意思,笔误笔误.红色部分是一样的。


多谢你的脚本,不过本人太菜,看awk的还是晕晕乎乎的

论坛徽章:
0
10 [报告]
发表于 2007-09-29 18:22 |只看该作者
如果是笔误


  1.     dn:*)
  2.       CN=${line#*:}
  3.       CN=${CN%%,*}
  4.       CN=${CN#*=}
  5.       ;;
复制代码

修改成

  1.     cn:*)
  2.       CN=${line#*:}
  3.       ;;
复制代码


我还以为是不同呢,所以特意用dn来判断
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP