快捷搜索:   nginx

Linux awk 文本处理(2)


                 the output of date(1) is used. See the specification for the
                 strftime() function in ANSI C for the format conversions that
                 are guaranteed to be available. A public-domain version of
                 strftime(3) and a man page for it come with gawk; if that
                 version was used to build gawk, then all of the conversions
                 described in that man page are available to gawk.                                                                                  
                                                                                  
这里举例说明时间戳函数是如何使用的

[root@ent root]# date +%s | awk '{print strftime("%F %T",$0)}'
2008-02-19 15:59:19        

我们先使用date命令做一个时间戳,然后再把他转换为时 间                                                                                             
还有一些我们现在可能不经常用到的函数,详细内容man awk 自己可以看一下。
Bit Manipulations Functions   二进制函数
Internationalization Functions 国际标准化函数

USER-DEFINED FUNCTIONS      用户也可以自己定义自己的函数,感兴趣自己可以再深入研究一下。

For example:

              function f(p, q,     a, b)   # a and b are local
              {
                   ...
              }

              /abc/     { ... ; f(1, 2) ; ... }
DYNAMICALLY LOADING NEW FUNCTIONS 动态加载新函数,这个可能就更高级一些了!
================================================================================
awk高级篇

不管学习任何语言,我们学到的都是工具,工具知道的越多,我们做起工作来就越方便,但是工具在你的手里并不一定能造出好的产品,编辑脚本和编程序也是一样 的重要的是算法,别人不知道怎么处理的问题你要知道如何处理。这才能证明你比别人更高,工具只要你慢慢练习都会使用。

    下面给大家一个我认为是比较高级的问题了,感兴趣的可以自己再想想更好的解决办法。问题是这样的我们有一个从ldap里导出的文件,它都是一行一个字段来 说明的,每个用户的数据是已空行分割的。我们必须把对应的uid 和userPassword找出来而且是对应的。
   
    例子:example4.txt
   
dn: uid=cailiying,domain=ccc.com.cn,o=mail.ccc.com.cn
uid: cailiying
userPassword:: e21kNX0zREl4VEIwODBJdXZkTnU3WFFtS3lRPT0=
letters: 300
quota: 100

dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
letters: 300
quota: 100
uid: chenzheng
domain: cqc.com.cn

dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
letters: 300
quota: 100

dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
letters: 300
quota: 100
uid: chenzheng
domain: cqc.com.cn
                                                                                    处理这个文本我们需要考虑的问题是:
1 uid 和userPassword 并不是每一个段落里都有
2 在每一段里面uid和userPassword 先后顺序是随机的
3 有的段落里可能只有uid 或者只有userPassword

从文本上分析可以看出必须使用的间隔符号,一个是空行,一个是冒号。
冒号我们awk -F:就可以了,不过空行我们不好判断现在想到length()这个函数,在unix里空行最多只有一个\n字符,如果一行字符数小于2我们判断为空行, 好现在间隔符号问题解决,空行只能通过循环来实现对空行的判断。                                        

现在碰到的另外一个问题是我们的某个段里的信息是不完全的,我们就要放弃这段这儿如何来做,就是要做两个标记变量u 和 p 再做一个循环如果u 和 p 同事满足我们才输出结果下面的awk脚本就是通过这个思考来解决ldif文本的处理的!

# 此脚本的目的是方便我们以后导ldap的其他邮件的数据,
# 我们之前使用slapdcat -l 导出所有信息,然后我们需要
# 整理出uid password , 这里的设置都是默认以":" 间隔的
# 例slapcat -l user.ldif 如果想得到一份uid 和userPassword 对应的文件,
# 修改username = "dn"; password = "userpassword"; awk -f ldap2txt.awk user.ldif | grep uid | more 可以查看结果 (有可能是多域的邮件)
# 如果想得到domain 所对应的密码,修改username = "dn"; password = "userpassword"; 运行 awk -f ldap2txt.awk user.ldif |grep domain | more

#!/bin/awk -f
# File name: ldap2txt.awk

BEGIN {
        FS = ":";
        username = "uid";
        password = "userPassword";
}

{

        if(length($0) == 0 )
        {
                if (name != "u" && pword != "p")
                {
                        printf ("%s:%s\n", name,pword);
                        name = "u";
                        pword = "p";
                }
        }

        else
        {
                if ($1 == username)
                {
                name = "u";
                name = $0;
                }
                else if($1 == password)
                {
                pword = "p";
                pword = $0;
                }
        }
}
END {

}

实际上对于学习语言首先是熟悉一些常用的函数,然后就是试着去解决别人解决过的问题,然后自己再思考一下是不是有更好,速度更快的解决办法,实际上 大部分的程序员都是在重复的使用着别人好的解决办法,把别人的方法转变为自己的方法,就是反复练习解决不同的问题,思考更好的方法!  


顶(0)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论