【工作经历:阿里巴巴搜索技术研发中心QA ,百度新产品测试部QA】 【领域:测试分析,自动化测试,性能测试,安全测试 】 【个人定位:高级测试工程师+培训师+领域产品专家】

发布新日志

  • 使用shell函数实现Linux下操作自动化

    2009-02-27 11:47:01

    练习shell的总结。
    函数库中的部门代码
    远程执行命令,传送文件,或者文件同步。自动输入密码。需要expect的支持。
    常在linux下操作的话,这些肯定是容易用到的。绿色的。不用使用rexec和rsync。
    更方便。存入文件,source 一下即可。

    用法
    登陆  se ip/主机名
    gexec ip/主机名  ip/主机名  'cmd'
    gsyn ip/主机名  ip/主机名  文件或者目录的位置

    #ssh login or execute comd
    se()
    {
        [[ -z $1 ]]&& echo se se3 who
        [[ "$1" > = ]]&&host=$1.xxxxx.com||host=119.42.239.$1
        ssh $host $2

    }

    #execute cmd in group, example, gexec se2 se3 35 'ps -x'
    gexec()
    {
        for i in ${*:1:$#-1};
        do
            [[ $i > = ]]&&host=$i.xxxxx.com||host=119.42.239.$i
            ex ssh $host ${*:$#}
        done
    }

    #distribute directorys or files, example, gsyn se2 se3 35 ~/dir
    gsyn()
    {
        cd `dirname ${*:$#}`
        cd $OLDPWD
        for i in ${*:1:$#-1};
        do  
            [[ $i > = ]]&&host=$i.xxxxx.com||host=119.42.239.$i  
            ex scp -r ${*:$#} $host:$OLDPWD/
        done
    }

    gscp()
    {
        for i in ${*:1:$#-2};
        do
            [[ $i > = ]]&&host=$i.xxxxx.com||host=119.42.239.$i
            ex scp -r ${*:$#-1:1} $host:~/${*:$#}      
        done
    }

    check()
    {
        if [ $# = 0 ]
        then
            echo "check ip|file|config string"
            return
        fi
        case $* in
            file)
            find . -name "*.*" | xargs grep /home/.* | awk -F/home '{print $1":/home"$2}'| sed -e 's/[^a-zA-Z0-9]*$//'|awk -F: '{gsub("\""," ");system("if [ ! -e  "$3" ] ;then echo \""$0"\" ;fi;")}'
            echo "WARNNING, those files wasn't exist,please check "
            ;;
            ip)
            find . -name "*.*" |xargs grep "[1-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
            ;;
            *)
            ls|xargs grep "$1"
            temp=`ls|xargs grep "$1"|sed -n $3p|uniq`      
            if [[ -n $2 ]]
            then
                temp=`echo $temp|awk -F= '{print $2}'`
                [[ $temp = "$2" ]]&&print OK||print WARNNING
            fi
            ;;
        esac
    }

    #set for load seven.sh when login
    autostart()
    {
        sed -i -e '/source seven/d' ~/.bashrc
        echo "source seven.sh ||: ; source /home/huangysh/seven.sh ||:" >>~/.bashrc && print "OK, you already have the power of qa shell functions, good luck"  
    }

    #the core of whole script. used for automation
    ex()
    {
        expect -c "set timeout -1;spawn $*; while {1} {expect eof {puts \nEX_OK\n;exit}  Password {puts Password;send ${PW}\n}  (yes/no)? {puts EX_YES;send yes\n}  timeout {puts EX_TIMEOUT;interact} }"
    }


  • 使用iostat分析linux的io性能

    2009-02-24 12:37:17

    最近在做性能测试。发现集群中,有一个机器的io比较大。还不是太熟悉linux下的io如何评测。搜索到了如下的文章,挺好的,记录一下,分析io的一个不错的方法。


    # iostat -x 1 10
    Linux 2.6.18-92.el5xen    02/03/2009

    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               1.10    0.00    4.82   39.54    0.07   54.46

    Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
    sda               0.00     3.50  0.40  2.50     5.60    48.00    18.48     0.00    0.97   0.97   0.28
    sdb               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
    sdc               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
    sdd               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
    sde               0.00     0.10  0.30  0.20     2.40     2.40     9.60     0.00    1.60   1.60   0.08
    sdf              17.40     0.50 102.00  0.20 12095.20     5.60   118.40     0.70    6.81   2.09  21.36
    sdg             232.40     1.90 379.70  0.50 76451.20    19.20   201.13     4.94   13.78   2.45  93.16

    rrqm/s:   每秒进行 merge 的读操作数目。即 delta(rmerge)/s
    wrqm/s:  每秒进行 merge 的写操作数目。即 delta(wmerge)/s
    r/s:           每秒完成的读 I/O 设备次数。即 delta(rio)/s
    w/s:         每秒完成的写 I/O 设备次数。即 delta(wio)/s
    rsec/s:    每秒读扇区数。即 delta(rsect)/s
    wsec/s:  每秒写扇区数。即 delta(wsect)/s
    rkB/s:      每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。(需要计算)
    wkB/s:    每秒写K字节数。是 wsect/s 的一半。(需要计算)
    avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)。delta(rsect+wsect)/delta(rio+wio)
    avgqu-sz: 平均I/O队列长度。即 delta(aveq)/s/1000 (因为aveq的单位为毫秒)。
    await:    平均每次设备I/O操作的等待时间 (毫秒)。即 delta(ruse+wuse)/delta(rio+wio)
    svctm:   平均每次设备I/O操作的服务时间 (毫秒)。即 delta(use)/delta(rio+wio)
    %util:      一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的。即 delta(use)/s/1000 (因为use的单位为毫秒)

    如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘
    可能存在瓶颈。
    idle小于70% IO压力就较大了,一般读取速度有较多的wait.

    同时可以结合vmstat 查看查看b参数(等待资源的进程数)和wa参数(IO等待所占用的CPU时间的百分比,高过30%时IO压力高)

    另外还可以参考
    svctm 一般要小于 await (因为同时等待的请求的等待时间被重复计算了),svctm 的大小一般和磁盘性能有关,CPU/内存的负荷也会对其有影响,请求过多也会间接导致 svctm 的增加。await 的大小一般取决于服务时间(svctm) 以及 I/O 队列的长度和 I/O 请求的发出模式。如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明 I/O 队列太长,应用得到的响应时间变慢,如果响应时间超过了用户可以容许的范围,这时可以考虑更换更快的磁盘,调整内核 elevator 算法,优化应用,或者升级 CPU。
    队列长度(avgqu-sz)也可作为衡量系统 I/O 负荷的指标,但由于 avgqu-sz 是按照单位时间的平均值,所以不能反映瞬间的 I/O 洪水。


      别人一个不错的例子.(I/O 系统 vs. 超市排队)

    举一个例子,我们在超市排队 checkout 时,怎么决定该去哪个交款台呢? 首当是看排的队人数,5个人总比20人要快吧? 除了数人头,我们也常常看看前面人购买的东西多少,如果前面有个采购了一星期食品的大妈,那么可以考虑换个队排了。还有就是收银员的速度了,如果碰上了连 钱都点不清楚的新手,那就有的等了。另外,时机也很重要,可能 5 分钟前还人满为患的收款台,现在已是人去楼空,这时候交款可是很爽啊,当然,前提是那过去的 5 分钟里所做的事情比排队要有意义 (不过我还没发现什么事情比排队还无聊的)。

    I/O 系统也和超市排队有很多类似之处:

    r/s+w/s 类似于交款人的总数
    平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数
    平均服务时间(svctm)类似于收银员的收款速度
    平均等待时间(await)类似于平均每人的等待时间
    平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少
    I/O 操作率 (%util)类似于收款台前有人排队的时间比例。

    我们可以根据这些数据分析出 I/O 请求的模式,以及 I/O 的速度和响应时间。

    下面是别人写的这个参数输出的分析

    # iostat -x 1
    avg-cpu: %user %nice %sys %idle
    16.24 0.00 4.31 79.44
    Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
    /dev/cciss/c0d0
    0.00 44.90 1.02 27.55 8.16 579.59 4.08 289.80 20.57 22.35 78.21 5.00 14.29
    /dev/cciss/c0d0p1
    0.00 44.90 1.02 27.55 8.16 579.59 4.08 289.80 20.57 22.35 78.21 5.00 14.29
    /dev/cciss/c0d0p2
    0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

    上面的 iostat 输出表明秒有 28.57 次设备 I/O 操作: 总IO(io)/s = r/s(读) +w/s(写) = 1.02+27.55 = 28.57 (次/秒) 其中写操作占了主体 (w:r = 27:1)。

    平均每次设备 I/O 操作只需要 5ms 就可以完成,但每个 I/O 请求却需要等上 78ms,为什么? 因为发出的 I/O 请求太多 (每秒钟约 29 个),假设这些请求是同时发出的,那么平均等待时间可以这样计算:

    平均等待时间 = 单个 I/O 服务时间 * ( 1 + 2 + ... + 请求总数-1) / 请求总数

    应用到上面的例子: 平均等待时间 = 5ms * (1+2+...+28)/29 = 70ms,和 iostat 给出的78ms 的平均等待时间很接近。这反过来表明 I/O 是同时发起的。

    每秒发出的 I/O 请求很多 (约 29 个),平均队列却不长 (只有 2 个 左右),这表明这 29 个请求的到来并不均匀,大部分时间 I/O 是空闲的。

    一秒中有 14.29% 的时间 I/O 队列中是有请求的,也就是说,85.71% 的时间里 I/O 系统无事可做,所有 29 个 I/O 请求都在142毫秒之内处理掉了。

    delta(ruse+wuse)/delta(io) = await = 78.21 => delta(ruse+wuse)/s =78.21 * delta(io)/s = 78.21*28.57 = 2232.8,表明每秒内的I/O请求总共需要等待2232.8ms。所以平均队列长度应为 2232.8ms/1000ms = 2.23,而 iostat 给出的平均队列长度 (avgqu-sz) 却为 22.35,为什么?! 因为 iostat 中有 bug,avgqu-sz 值应为 2.23,而不是 22.35。

  • Linux下的web基准测试工具

    2009-02-08 01:56:16

    631     2009-02-08 01:12 = huangysh
    632     2009-02-08 01:34 a huangysh
    633     2009-02-08 01:56 a huangysh
    634     2009-02-08 02:18 a huangysh
    635     2009-02-08 02:40 a huangysh
    636     2009-02-08 03:02 a huangysh
    637     2009-02-08 03:24 a huangysh
    638     2009-02-08 03:46 a huangysh
    639     2009-02-08 04:08 a huangysh
    640     2009-02-08 14:00 a huangysh
    641     2009-02-08 14:22 a huangysh
    642     2009-02-08 14:44 a huangysh
    643     2009-02-08 15:06 a huangysh
    644     2009-02-08 15:28 a huangysh
    645     2009-02-08 15:50 a huangysh
    646     2009-02-08 16:12 a huangysh
    647     2009-02-08 16:34 a huangysh
    648     2009-02-08 16:56 a huangysh
    649     2009-02-08 17:18 a huangysh
    650     2009-02-08 17:40 a huangysh
    651     2009-02-08 18:02 a huangysh
    652     2009-02-08 18:24 a huangysh
    653     2009-02-08 18:46 a huangysh
    654     2009-02-08 19:08 a huangysh

    可怜啊,公司的服务器。
    利用服务器空闲的时候,我一直在做一些测试。短短一个星期。
    定时任务的序号已经排到了600多。
    利用自己写的脚本,我添加了N多的测试任务。
    去验证测试工具,验证某些服务的性能。
    数据收集了不少,分析了一下,感觉自己对公司的性能测试的工具已经比较熟悉了。
    对服务器的负载曲线图也终于可以了如指掌了。

    还没有太好的测试工具,不同的工具,同样的服务,测试出来的结果却各有差距。哎。
    部分工具是用c写的。我想用ruby或者python去模拟一下,自己去写一个工具。
    因为ruby或者python的特性,代码肯定会精简不少。
    然后使用自己写的工具,可以在测试的时候,插入额外的请求,来判断处于压力状态下的服务的性能和响应时间等指标。就像探针一样。

    不少人担心ruby和python的效率。其实运行的时候,差别是很小很小的。人们感觉他们慢,是因为启动的时候,有明显的延迟,而实际上,运行时的速度是丝毫不逊色的。

    另外,在http://chinaonrails.com/topic/view/903.html 上发现了更多的测试工具。
    我打算使用工作之余的时间,慢慢试验他们。得出数据,参考一下。然后确定一款合适的工具,
    总结好测试的策略。
    彻底的消灭掉测试中发现的问题。





  • Linux shell应用心得

    2009-01-16 17:13:27

    经过了一段时间的学习,还有在项目中的使用。已经深深的喜欢上它了。
    经过了几个月的积累,我的函数库已经足够强大了。
    现在自己的效率已经是同事的N倍了。越来越多的任务,开始使用shell去自动化完成了。

    让自己自豪的一件事情,就是当初我决定编写自己的函数库。当初的决定,让自己受用匪浅。
    同事发现后,感觉挺好,就鼓励我推广一下。现在已经开始教同事学习shell。
    呵呵,小小的成就,庆祝一下。

    那个函数库,的确花费了自己不少的心血。搜索了很多资料,一点一滴的改进,才到了今天这个地步。
    现在同事感到很有用,我还是非常欣慰的。
    这一年,主要是为同事做事,下一年开始我就要专心为自己的发展着想了。
    同事都转正了,就剩下我还没有转正。好伤心。
    努力做好吧,不做最好,就离开。
    暂时还不想离开这个岗位。公司的环境挺好,喜欢那种氛围。



  • linux core文件机制

    2009-01-15 19:48:22

    在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。


    1.core文件的生成开关和大小限制
    ---------------------------------
     1)使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。
     2) 使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。若ulimit -c unlimited,则表示core文件的大小不受限制。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件。在调试此core文 件的时候,gdb会提示错误。


    2.core文件的名称和生成路径
    ----------------------------
    core文件生成路径:
    输入可执行文件运行命令的同一路径下。
    若系统生成的core文件不带其它任何扩展名称,则全部命名为core。新的core文件生成将覆盖原来的core文件。

    1)/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作为扩展。文件内容为1,表示添加pid作为扩展名,生成的core文件格式为core.xxxx;为0则表示生成的core文件同一命名为core。
    可通过以下命令修改此文件:
    echo "1" > /proc/sys/kernel/core_uses_pid

    2)proc/sys/kernel/core_pattern可以控制core文件保存位置和文件名格式。
    可通过以下命令修改此文件:
    echo "/corefile/core-%e-%p-%t" > core_pattern,可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
    以下是参数列表:
        %p - insert pid into filename 添加pid
        %u - insert current uid into filename 添加当前uid
        %g - insert current gid into filename 添加当前gid
        %s - insert signal that caused the coredump into the filename 添加导致产生core的信号
        %t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间
        %h - insert hostname where the coredump happened into filename 添加主机名
        %e - insert coredumping executable name into filename 添加命令名

     


    3.core文件的查看
    -----------------
     core文件需要使用gdb来查看。
     gdb ./a.out
     core-file core.xxxx
     使用bt命令即可看到程序出错的地方。
    以下两种命令方式具有相同的效果,但是在有些环境下不生效,所以推荐使用上面的命令。
    1)gdb -core=core.xxxx
    file ./a.out
    bt
    2)gdb -c core.xxxx
    file ./a.out
    bt


    4.开发板上使用core文件调试
    -----------------------------
    如果开发板的操作系统也是linux,core调试方法依然适用。如果开发板上不支持gdb,可将开发板的环境(依赖库)、可执行文件和core文件拷贝到PC的linux下。
    在 PC上调试开发板上产生的core文件,需要使用交叉编译器自带的gdb,并且需要在gdb中指定solib-absolute-prefix和 solib-search-path两个变量以保证gdb能够找到可执行程序的依赖库路径。有一种建立配置文件的方法,不需要每次启动gdb都配置以上变 量,即:在待运行gdb的路径下建立.gdbinit。
    配置文件内容:
    set solib-absolute-prefix YOUR_CROSS_COMPILE_PATH
    set solib-search-path YOUR_CROSS_COMPILE_PATH
    set solib-search-path YOUR_DEVELOPER_TOOLS_LIB_PATH
    handle SIG32 nostop noprint pass


    注意:待调试的可执行文件,在编译的时候需要加-g,core文件才能正常显示出错信息!有时候core信息很大,超出了开发板的空间限制,生成的core信息会残缺不全而无法使用,可以通过挂载到PC的方式来规避这一点。

  • awk教程

    2009-01-07 16:48:00

    很全~
    目录(Contents)

    1. awk简介
    2. awk命令格式和选项
        2.1. awk的语法有两种形式
        2.2. 命令选项

    3. 模式和操作
        3.1. 模式
        3.2. 操作

    4. awk的环境变量
    5. awk运算符
    6. 记录和域
        6.1. 记录
        6.2.
        6.3. 域分隔符

    7. gawk专用正则表达式元字符
    8. POSIX字符集
    9. 匹配操作符(~)
    10. 比较表达式
    11. 范围模板
    12. 一个验证passwd文件有效性的例子
    13. 几个实例
    14. awk编程
         14.1. 变量
         14.2. BEGIN模块
         14.3. END模块
         14.4. 重定向和管道
         14.5. 条件语句
         14.6. 循环
         14.7. 数组
         14.8. awk的内建函数

    15. How-to




    正文


    1. awk简介
          awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和 动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk的处理文本和数据的方式是这 样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出 (屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。gawk是awk的GNU版本,它提供了Bell实验室和GNU的一些扩展。下面介绍的awk是以GUN的gawk为例的,在 linux系统中已把awk链接到gawk,所以下面全部以awk进行介绍。



    2. awk命令格式和选项
          2.1. awk的语法有两种形式
    awk [options] 'scrīpt' var=value file(s)

    awk [options] -f scrīptfile var=value file(s)

          2.2. 命令选项

    -F fs or --field-separator fs
    指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。

    -v var=value or --asign var=value
    赋值一个用户定义变量。

    -f scripfile or --file scrīptfile
    从脚本文件中读取awk命令。

    -mf nnn and -mr nnn
    对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。

    -W compact or --compat, -W traditional or --traditional
    在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。

    -W copyleft or --copyleft, -W copyright or --copyright
    打印简短的版权信息。

    -W help or --help, -W usage or --usage
    打印全部awk选项和每个选项的简短说明。

    -W lint or --lint
    打印不能向传统unix平台移植的结构的警告。

    -W lint-old or --lint-old
    打印关于不能向传统unix平台移植的结构的警告。

    -W posix
    打开兼容模式。但有以下限制,不识别:\x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。

    -W re-interval or --re-inerval
    允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。

    -W source program-text or --source program-text
    使用program-text作为源代码,可与-f命令混用。

    -W version or --version
    打印bug报告信息的版本。



    3. 模式和操作
           awk脚本是由模式和操作组成的:
    pattern {action} 如$ awk '/root/' test,或$ awk '$3 < 100' test

          两者是可选的,如果没有模式,则action应用到全部记录,如果没有action,则输出匹配全部记录。默认情况下,每一个输入行都是一条记录,但用户可通过RS变量指定不同的分隔符进行分隔。

         3.1. 模式
         模式可以是以下任意一个:
         /正则表达式/:使用通配符的扩展集。
         关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
         模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
         模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
         BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
         END:让用户在最后一条输入记录被读取之后发生的动作。
       3.2. 操作
        操作由一人或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份:
        变量或数组赋值
        输出命令
        内置函数
        控制流命令

    4. awk的环境变量
    Table 1. awk的环境变量

    变量 描述
    $n 当前记录的第n个字段,字段间由FS分隔。
    $0 完整的输入记录。
    ARGC 命令行参数的数目。
    ARGIND 命令行中当前文件的位置(从0开始算)。
    ARGV 包含命令行参数的数组。
    CONVFMT 数字转换格式(默认值为%.6g)
    ENVIRON 环境变量关联数组。
    ERRNO 最后一个系统错误的描述。
    FIELDWIDTHS 字段宽度列表(用空格键分隔)。
    FILENAME 当前文件名。
    FNR 同NR,但相对于当前文件。
    FS 字段分隔符(默认是任何空格)。
    IGNORECASE 如果为真,则进行忽略大小写的匹配。
    NF 当前记录中的字段数。
    NR 当前记录数。
    OFMT 数字的输出格式(默认值是%.6g)。
    OFS 输出字段分隔符(默认值是一个空格)。
    ORS 输出记录分隔符(默认值是一个换行符)。
    RLENGTH 由match函数所匹配的字符串的长度。
    RS 记录分隔符(默认是一个换行符)。
    RSTART 由match函数所匹配的字符串的第一个位置。
    SUBSEP 数组下标分隔符(默认值是\034)。


    5. awk运算符
    Table 2. 运算符

    运算符 描述
    = += -= *= /= %= ^= **= 赋值
    ?: C条件表达式
    || 逻辑或
    && 逻辑与
    ~ ~! 匹配正则表达式和不匹配正则表达式
    < <= > >= != == 关系运算符
    空格 连接
    + - 加,减
    * / & 乘,除与求余
    + - ! 一元加,减和逻辑非
    ^ *** 求幂
    ++ -- 增加或减少,作为前缀或后缀
    $ 字段引用
    in 数组成员


    6. 记录和域
       6.1. 记录
         awk把每一个以换行符结束的行称为一个记录。
         记录分隔符:默认的输入和输出的分隔符都是回车,保存在内建变量ORS和RS中。
         $0变量:它指的是整条记录。如$ awk '{print $0}' test将输出test文件中的所有记录。
         变量NR:一个计数器,每处理完一条记录,NR的值就增加1。如$ awk '{print NR,$0}' test将输出test文件中所有记录,并在记录前显示记录号。

      6.2.
         记录中每个单词称做“域”,默认情况下以空格或tab分隔。awk可跟踪域的个数,并在内建变量NF中保存该值。如$ awk '{print $1,$3}' test将打印test文件中第一和第三个以空格分开的列(域)。
        6.3. 域分隔符
         内建变量FS保存输入域分隔符的值,默认是空格或tab。我们可以通过-F命令行选项修改FS的值。如$ awk -F: '{print $1,$5}' test将打印以冒号为分隔符的第一,第五列的内容。
         可以同时使用多个域分隔符,这时应该把分隔符写成放到方括号中,如$awk -F'[:\t]' '{print $1,$3}' test,表示以空格、冒号和tab作为分隔符。
         输出域的分隔符默认是一个空格,保存在OFS中。如$ awk -F: '{print $1,$5}' test,$1和$5间的逗号就是OFS的值。
    7. gawk专用正则表达式元字符
         一般通用的元字符集就不讲了,可参考我的Sed和Grep学习笔记。以下几个是gawk专用的,不适合unix版本的awk。
    \Y
    匹配一个单词开头或者末尾的空字符串。
    \B
    匹配单词内的空字符串。
    \<
    匹配一个单词的开头的空字符串,锚定开始。
    \>
    匹配一个单词的末尾的空字符串,锚定末尾。
    \w
    匹配一个字母数字组成的单词。
    \W
    匹配一个非字母数字组成的单词。
    \‘
    匹配字符串开头的一个空字符串。
    \'
    匹配字符串末尾的一个空字符串。

    8. POSIX字符集
    待完善
    9. 匹配操作符(~)
    用来在记录或者域内匹配正则表达式。如$ awk '$1 ~/^root/' test将显示test文件第一列中以root开头的行。
    10. 比较表达式

    conditional expression1 ? expression2: expression3

    例如:

    $ awk '{max = {$1 > $3} ? $1: $3: print max}' test

    如果第一个域大于第三个域,$1就赋值给max,否则$3就赋值给max。

    $ awk '$1 + $2 < 100' test

    如果第一和第二个域相加大于100,则打印这些行。

    $ awk '$1 > 5 && $2 < 10' test

    如果第一个域大于5,并且第二个域小于10,则打印这些行。
    11. 范围模板
    范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,则匹配到开头或末尾。如$ awk '/root/,/mysql/' test将显示root第一次出现到mysql第一次出现之间的所有行。
    12. 一个验证passwd文件有效性的例子

    $ cat /etc/passwd | awk -F: '\
    NF != 7{\
    printf("line %d,does not have 7 fields:%s\n",NR,$0)}\
    $1 !~ /[A-Za-z0-9]/{printf("line %d,non alpha and numeric user id:%d: %s\n,NR,$0)}\
    $2 == "*" {printf("line %d, no password: %s\n",NR,$0)}'

    cat把结果输出给awk,awk把域之间的分隔符设为冒号。
    如果域的数量(NF)不等于7,就执行下面的程序。
    printf打印字符串"line ?? does not have 7 fields",并显示该条记录。
    如果第一个域没有包含任何字母和数字,printf打印“no alpha and numeric user id" ,并显示记录数和记录。
    如果第二个域是一个星号,就打印字符串“no passwd”,紧跟着显示记录数和记录本身。
    13. 几个实例
    打印所有以模式no或so开头的行。

    $ awk '/^(no|so)/' test

    如果记录以n或s开头,就打印这个记录。

    $ awk '/^[ns]/{print $1}' test

    如果第一个域以两个数字结束就打印这个记录。

    $ awk '$1 ~/[0-9][0-9]$/(print $1}' test

    如果第一个或等于100或者第二个域小于50,则打印该行。

    $ awk '$1 == 100 || $2 < 50' test

    如果第一个域不等于10就打印该行。

    $ awk '$1 != 10' test

    如果记录包含正则表达式test,则第一个域加10并打印出来。

    $ awk '/test/{print $1 + 10}' test

    如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。

    $ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test

    打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。

    $ awk '/^root/,/^mysql/' test



    14. awk编程
    14.1. 变量
    在awk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串。
    赋值格式:

    Variable = expression,如$ awk '$1 ~/test/{count = $2 + $3; print count}' test
    上式的作用是,awk先扫描第一个域,一旦test匹配,就把第二个域的值加上第三个域的值,并把结果赋值给变量count,最后打印出来。
          awk可以在命令行中给变量赋值,然后将这个变量传输给awk脚本。如
    $ awk -F: -f awkscrīpt month=4 year=2004 test
    上式的month和year都是自定义变量,分别被赋值为4和2004。在awk脚本中,这些变量使用起来就象是在脚本中建立的一样。注意,如果参数前面出现test,那么在BEGIN语句中的变量就不能被使用。
          域变量也可被赋值和修改,如

    $ awk '{$2 = 100 + $1; print }' test
    上式表示,如果第二个域不存在,awk将计算表达式100加$1的值,并将其赋值给$2,如果第二个域存在,则用表达式的值覆盖$2原来的值。再例如:
    $ awk '$1 == "root"{$1 ="test";print}' test
    如果第一个域的值是“root”,则把它赋值为“test”,注意,字符串一定要用双引号。
          内建变量的使用。变量列表在前面已列出,现在举个例子说明一下。

    $ awk -F: '{IGNORECASE=1; $1 == "MARY"{print NR,$1,$2,$NF}'test
    把IGNORECASE设为1代表忽略大小写,打印第一个域是mary的记录数、第一个域、第二个域和最后一个域。

  • 重新学习Chilkat Python Library

    2008-11-25 20:30:33

    最近对python关注越来越少了,好久没有看python书了。很多东西都忘记了。

    今天同事让我帮忙解释一段perl,虽然不会,但是因为看多了其他的语言,也可以讲出了大概。
    还动手帮他修改了部分代码。

    语言还是不能丢的。

    python3.0已经出来了,完全不兼容python2.*。所以,也不打算去学习python3.0,应用为主。等成熟了再说。下载了不少python的东西,打算好好学习一番。


    利用一个月的时间,学习了很多的shell,总结了很多非常好的脚本。一直自己用。
    非常方便。这是自己的特长,还是要保留的。

    Chilkat Python Library是以前自己发现的一个不错的库,虽然有很多的限制,但是还是比较适合进行短期开发什么工具的。不再从底层开始了,开始学习如何站在别人的肩上思考和解决问题。

    继续积累。



  • expect的用法

    2008-11-14 11:42:25

    expect -c "spawn ssh se2.asc.cnz.xxx.com echo xsss; while {1} {expect ass {send cccc\n} eof exit "yes" interact}"



    终于找到了可以处理程序提示的方法了。真是不容易啊 。摸索了好几天。
    这个方法真好,以后自动化的工作就可以更加的智能化了。
  • 我放弃ruby的原因(我不是高手)

    2008-11-06 11:37:17

    1、python自己已经学习了一阵子了,已经可以简单应用了。而ruby我还没有基础。
    公司的项目组使用ruby的还是在少数的,而且使用python的也并不比ruby少。


    2、ruby是日本人开发的。python是美国人开发的。这就意味着我无法去阅读最新的ruby信息,以及相关的知识。虽然ruby的所有信息,都可以在英文网站上找到。但是还是有一种心理隔阂。更何况,是日本人,不是中国人。

    3、我有一个德国朋友,他说他们国内的python地位和c的地位是差不多的。python在国外很火。ruby就稍逊一点。根据开发语言排行榜上来看,ruby已经开始停滞了,而python还是迅猛发展。

    4、python拥有众多的源代码,开发库,包括嗅探,搜索,爬虫,hook,sql注入,xss扫描,自动化。非常全面。而且诺基亚的手机系统也支持python。ruby的相关库暂时还不是太多。也没有python的全面。

    5、我本人也写了很多代码,用起来比较方便。ruby还没有接触。

    6、ruby比python快,但是我追求应用,不追求速度。扩且python还是可以优化的,而且速度差别也不是太大。

    7、我更喜欢python的语法。简约。

    8、我精力有限。时间有限。





  • 放弃ruby

    2008-11-05 10:47:58

    现在对公司已经算是比较了解了。经过对ruby使用的仔细询问。终于发现ruby的使用率还是很低的。还不及python。而且他们说,不需要仔细去研究,简单的参考别人的就可以应付了。呵呵。

    看来我和python还是有缘的,这样的话,我的ruby cookbook真的是用处不大了。
    有点失算。不过还是挺开心的。因为我可以继续研究我的python了。

    我要充分发挥python的优点,让这个工具,成为我办公,自动化,hack的利器。

    重新投入python的事业中。

  • linux下的有用的几个小命令

    2008-10-27 16:16:07

    ctrl+r
    这个命令可以让你快速的定位以前输入过的命令,非常的好用。

    查看自己的进程 
    很多人喜欢ps -aux | grep "自己的名字",其实ps -ux 就可以了。

    查看端口,经常使用apache和tomcat,或者其他的网络服务器,在开启后如果遇到一些问题。可以先确认一下端口是否开启,可以提供你一些信息。

    netstat -tulp

    某些程序配置有问题,尤其是牵扯到集群服务的,不知道到底是那一个节点上出问题,就可以使用

    sudo tcpdump host ip地址 and port 端口号
    可以看出本机发送了那些请求,如果怀疑有问题,还可以继续分析监听的数据。

    配置文件的时候,需要配置很多各个文件的地址参数,而且这些配置文件是互相指向的。去查证他们很麻烦。
    就可以利用如下命令。

    鱼鱼多媒体日记本
    查找相关的配置文件,从里面过滤出里面再次引用的其他文件的地址。
    find 目录名字/ -name "*.conf" | xargs sed -n -e "/.*\.conf/p" | sed -n -e "/^[^#]/p" | sed -n -e "s/\.conf.*/\.conf/p"
     
    过滤出含有绝对路径的文件地址
    find 目录名字/ -name "*.conf" | xargs sed -n -e "/.*\.conf/p" | sed -n -e "/^[^#]/p" | sed -n -e "s/\.conf.*/\.conf/p" |sed -n -e "s/.*\/home/\/home/p"
     
     利用ls判断这些地址是否有错误。
    find 目录名字/ -name "*.conf" | xargs sed -n -e "/.*\.conf/p" | sed -n -e "/^[^#]/p" | sed -n -e "s/\.conf.*/\.conf/p" |sed -n -e "s/.*\/home/\/home/p" | xargs ls
     

  • 买了《ruby cookbook》

    2008-10-23 21:00:59

    虽然有了电子版,但是还是忍不住买下来了。
    or出的是,一向是经典之作。

    没有一本书放在手里,总是感觉不踏实。就当时是学习英语了。

    以前买过python handbook,非常的好。从此也燃起来了自己的python激情。
    第一次感到了这种解释性语言的魅力。

    公司需要ruby,只好转行。
    从网上搜索了一下“ruby 嗅探” ,发现资料很少。
    然后搜索“python 嗅探”,比ruby多些。
    百度出来的第一个结果竟然是我以前发的一片文章。
    其实还是python的应用范围广一些。
    考虑了很久,感觉python还是不可以丢。最起码自己玩黑客还是用得着的。
    ruby是日本人发明的。这样很容易受制于一些客观因素。
    不过把工作搞定就可以了。

    虽然精力不够,但是两者还是都不能放掉的。



  • sed最全的用法

    2008-10-22 13:54:53

    本来以为对sed的使用已经娴熟于心了。后来查看一切其他的发行安装软件里,有对sed更高深的用法。
    于是就搜索出了sed的大量用法。

    整理一下,我已经打印出来了,也共享一下吧。总共21页。
    用这个东西来进行自动修改配置,可以方便很多,大大节省自己的劳动力。呵呵。

    ============================================================

    SED 手册 - 1. Introduction

    http://phi.sinica.edu.tw aspac@phi.sinica.edu.tw (2001-07-29 08:05:00)

     

    1.Introduction

      Sed(Stream EDitor) UNIX 系统上提供将编辑工作自动化的编辑器 , 使用者无需直接编辑资料。使用者可

      利用 sed 所提供 20 多种不同的函数参数 , 组合( [1])它们完成不同的编辑动作。此外 , 由於 sed

      以行为单位编辑文件 , 故其亦是行编辑器(line editor)

      一般 sed 最常用在编辑那些需要不断重覆某些编辑动作的文件上 , 例如将文件中的某个字串替换成另一个字

      串等等。这些相较於一般 UNIX 编辑器(交谈式的, viemacs)用手动的方式修改文件 , sed 用起来较省力。

      下面几节将分别介绍:

     

    何时使用 sed

    何处获得 sed

    sed 能做那些编辑动作

    sed 如何工作

    1.1 何时使用 sed

      在修改文件时 , 如果不断地重覆某些编辑动作 , 则可用 sed 自动一次执行这些编辑动作。例如要使 received

      档内 1000 封电子信件内的发信人属名 "Tom" 改成 "John" , 此时只要在命令列上执行一简单的 sed 命令就可

      把档内所有的 "Tom" 字串替换成 "John"

      再者 , 当文件需要许多不同编辑动作时 , sed 一次可执行那些不同的编辑动作。例如 sed 能一次执行完将

      文件中所有空白行删除、替换字串、并将使用者输入的文字添加在文件的第六行等等不同的编辑动作。

     

     

    1.2 何处获得 sed

      一般的 UNIX 系统 , 本身即附有 sed。不同的 UNIX 系统所附的 sed 版本亦不尽相同。若读者所使用的 UNIX

      系统上未附有 sed , 则可透过 anonymous ftp 到下列地方去取得 :

    phi.sinica.edu.tw:/pub/GNU/gnu

    gete.sinica.edu.tw:/unix/gnu

    ftp.edu.tw:/UNIX/gnu

    ftp.csie.nctu.edu.tw:/pub/Unix/GNU

    ftp.fcu.edu.tw: /pub3/UNIX/gnu

    axp350.ncu.edu.tw:/Packages/gnu

    leica.ccu.edu.tw :/pub2/gnu

    mail.ncku.edu.tw :/pub/unix/gnu

    bbs.ccit.edu.tw :/pub1/UNIX/gnu

    prep.ai.mit.edu.tw:/pub/gnu

     

    1.3 sed 能做那些编辑动作

      sed 可删除(delete)、改变(change)、添加(append)、插入(insert)、合、交换文件中的资料行 , 或读入其它

      档的资料到文件中 , 也可替换(substuite)它们其中的字串、或转换(tranfer)其中的字母等等。例如将文件中的

      连续空白行删成一行、 "local" 字串替换成 "remote" "t" 字母转换成 "T"、将第 10 行资料与第 11 资料合

      等。

     

    1.4 sed 如何工作

      如同其它 UNIX 命令 , sed 由标准输入读入编辑文件并由标准输出送出结果。下图表示 sed 将资料行 "Unix"

      换成 "UNIX" ,

     

     

     

    在图中 , 上方 standard input 为标准输入 , 是读取资料之处 ; standard output 为标准输出 , 是送出结果之处 ;

    中间 sed 方块的下面两个虚线方块表示 sed 的工作流程。其中 , 左边虚线方块表示 sed 将标准输入资料置入

    pattern space , 右边虚线方块表示 sed pattern space 中编辑完毕後的资料送到标准输出。

     

    在虚线方块中 , 两个实线方块分别表示 pattern space sed scrīpt。其中 , pattern space 为一缓区 , 它是

    sed 工作场所 ; sed scrīpt 则表示一组执行的编辑指令。

     

    在图中, 左边虚线方块 "Unix" 由标准输入置入 pattern space ; 接着 , 在右边虚线方块中 , sed 执行 sed scrīpt

    中的编辑指令 s/Unix/UNIX/ ( [2]) , 结果 "Unix" 被替换成 "UNIX" , 之後 , "UNIX" pattern space 送到

    标准输出。

     

     

      总合上述所言 , sed 由标准输入读入一行资料并放入 pattern space , sed 依照 sed scrīpt 的编辑指令逐

      一对 pattern space 内的资料执行编辑 , 之後 , 再由 pattern space 内的结果送到标准输出 , 接着再将下一行资

      料读入。如此重执行上述动作 , 直至读完所有资料行为止。 

     

    SED 手册 - 2. 使用 sed

    http://phi.sinica.edu.tw aspac@phi.sinica.edu.tw (2001-07-29 09:05:00)

     

       Sed 命令列可分成编辑指令与文件档部份。其中 , 编辑指令负责控制所有的编辑工作 ; 文件档表示所处理的档案。

       sed 的编辑指令均由位址(address)与函数(function)两部份组成 , 其中 , 在执行时 , sed 利用它的位址参数来

       决定编辑的对象;而用它的函数参数([3])编辑。

       此外 , sed 编辑指令 , 除了可在命令列上执行 , 也可在档案内执行。其中差别只是在命令列上执行时 , 其前必

       须加上选项 -e ; 而在档案([4])内时 , 则只需在其档名前加上选项 -f。另外 , sed 执行编辑指令是依照它

       们在命令列上或档内的次序。

     

       下面各节 , 将介绍执行命令列上的编辑指令 、sed 编辑指令、执行档案内的编辑指令、执行多个档案的编辑、及

       执行 sed 输出控制。

     

    2.1 执行命令列上的编辑指令

    2.2 sed 编辑指令

    2.3 执行档案内的编辑指令

    2.4 执行多个档案的编辑

    2.5 执行 sed 输出控制

    2.1.执行命令列上的编辑指令

       当编辑指令(参照[section 2.2])在命令列上执行时 , 其前必须加上选项 -e 。其命令格式如下 :

         sed -e '编辑指令1' -e '编辑指令2' ... 文件档 

     

    其中 , 所有编辑指令都紧接在选项 -e 之後 , 并置於两个 " ' " 特殊字元间。另外 , 命令上编辑指令的执行是由

    左而右。

     

       一般编辑指令不多时 , 使用者通常直接在命令上执行它们。例如 , 删除 yel.dat 1 10 行资料 , 并将其

       馀文字中的 "yellow" 字串改成 "black" 字串。此时 , 可将编辑指令直接在命令上执行 , 其命令如下 :

     

         sed -e '1,10d' -e 's/yellow/black/g' yel.dat 

     

    在命令中 , 编辑指令 '1,10d'([5])执行删除 1 10 行资料 ; 编辑指令 's/yellow/black/g'([6]) ,

    "yellow" 字串替换(substuite) "black" 字串。

    2.2 sed 的编辑指令

       sed 编辑指令的格式如下 :

                  [address1[,address2]]function[argument]

     

    其中 , 位址参数 address1 address2 为行数或 regular expression 字串 , 表示所执行编辑的资料行 ; 函数参

    function[argument] sed 的内定函数 , 表示执行的编辑动作。

    下面两小节 , 将仔细介绍位址参数的表示法与有哪些函数参数供选择。

     

    2.2.1 位址(address)参数的表示法

       实际上 , 位址参数表示法只是将要编辑的资料行 , 用它们的行数或其中的字串来代替表示它们。下面举几个例子

       说明(指令都以函数参数 d(参照[section4.2]) 为例) :

    删除档内第 10 行资料 , 则指令为 10d

    删除含有 "man" 字串的资料行时 , 则指令为 /man/d

    删除档内第 10 行到第 200 行资料, 则指令为 10,200d

    删除档内第 10 行到含 "man" 字串的资料行 , 则指令为 10,/man/d

       接下来 , 以位址参数的内容与其个数两点 , 完整说明指令中位址参数的表示法(同样也以函数参数 d 为例)

    位址参数的内容:

    位址为十进位数字 : 此数字表示行数。当指令执行时 , 将对符合此行数的资料执行函数参数指示的编辑动作。例如 ,

    删除资料档中的第 15 行资料 , 则指令为 15d(参照[section4.2])。其馀类推 ,如删除资料档中的第 m 行资料 ,

    指令为 md

     

    位址为 regular expression(参照[附录 A]):

    当资料行中有符合 regular expression 所表示的字串时 , 则执行函数参数指示的编辑动作。另外 ,

    regular expression 前後必须加上 "/"。例如指令为 /t.*t/d , 表示删除所有含两 "t" 字母的资料行。其中 , "."

    表示任意字元; "*" 表示其前字元可重任意次 , 它们结合 ".*" 表示两 "t" 字母间的任意字串。

     

    位址参数的个数 : 在指令中 , 当没有位址参数时 , 表示全部资料行执行函数参数所指示的编辑动作; 当只有一位址

    参数时 , 表示只有符合位址的资料行才编辑 ; 当有两个位址参数 , address1,address2 , 表示对资料区执行

    编辑 , address1 代表起始资料行 , address2 代表结束资料行。对於上述内容 , 以下面例子做具说明。

     

    例如指令为

     

    d

     

    其表示删除档内所有资料行。

    例如指令为

     

    5d

     

    其表示删除档内第五行资料。

    例如指令为

     

    1,/apple/d

     

    其表示删除资料区 , 由档内第一行至内有 "apple" 字串的资料行。

    例如指令为

     

    /apple/,/orange/d

     

    其表示删除资料区 , 由档内含有 "apple" 字串至含有 "orange" 字串的资料行

    2.2.2 有那些函数(function)参数

       下页表中介绍所有 sed 的函数参数(参照[chapter 4])的功能。

    函数参数 功能

    : label  建立 scrīpt file 内指令互相参考的位置。 

    #  建立解 

    { }  集合有相同位址参数的指令。  

    !  不执行函数参数。 

    =  印出资料行数( line number ) 

    a\  添加使用者输入的资料。 

    b label  将执行的指令跳至由 : 建立的参考位置。 

    c\  以使用者输入的资料取代资料。

    d  删除资料。 

    D  删除 pattern space 内第一个 newline 字母 \ 前的资料。 

    g  拷贝资料从 hold space 

    G  添加资料从 hold space pattern space  

    h  拷贝资料从 pattern space hold space  

    H  添加资料从 pattern space hold space  

    l  印出 l 资料中的 nonprinting character ASCII 码。 

    i\  插入添加使用者输入的资料行。 

    n  读入下一笔资料。 

    N  添加下一笔资料到 pattern space 

    p  印出资料。 

    P  印出 pattern space 内第一个 newline 字母 \ 前的资料。 

    q  跳出 sed 编辑。 

    r  读入它档内容。 

    s  替换字串。 

    t label  先执行一替换的编辑指令 , 如果替换成牛p>则将编辑指令跳至 : label 处执行。 

    w  写资料到它档内。 

    x  交换 hold space pattern space 内容。 

    y  转换(transform)字元。 

    虽然 , sed 只有上表所述几个拥有基本编辑功能的函数 , 但由指令中位址参数和指令与指令间的配合 , 也能使

    sed 完成大部份的编辑任务。

    2.3 执行档案内的编辑指令

       当执行的指令太多 , 在命令列上撰写起来十分混乱 , 此时 , 可将这些指令整理储存在档案

       (譬如档名为 scrīpt_file ) , 用选项 -f scrīpt_file , 则让 sed 执行 scrīpt_file 内的编辑指令。其命

       令的格示如下 :

          sed -f scrīpt_file 文件档 

     

    其中 , 执行 scrīpt_file 内编辑指令的顺序是由上而下。例如上一节的例子 , 其可改成如下命令:

          sed -f ysb.scr yel.dat 

     

    其中 , ysb.scr 档的内容如下 :

    1,10d

    s/yellow/black/g

     

       另外 , 在命令列上可混合使用选项 -e -f , sed 执行指令顺序依然是由命令列的左到右, 如执行至 -f

       档案内的指令 , 则由上而下执行。

     

     

    2.4 执行多个文件档的编辑

       sed 命令列上 , 一次可执行编辑多个文件档 , 它们跟在编辑指令之後。例如 , 替换

        white.datred.datblack.dat 档内的 "yellow" 字串成 "blue" , 其命令如下:

           sed -e 's/yellow/blue/g' white.dat red.dat black.dat

     

    上述命令执行时 , sed white.datred.datblack.dat 顺序 , 执行编辑指令 s/yellow/blue/(请参照[section 4.1] ,

    进行字串的替换。

     

    2.5.执行输出的控制

       在命令列上的选项 -n ([7]) 表示输出由编辑指令控制。由前章内容得知 , sed "自动的" 将资料由

        pattern space 输送到标准输出档。但藉着选项 -n , 可将 sed "自动的" 的动作改成 "被动的" 由它所执行的

        编辑指令([8])来决定结果是否输出。

       由上述可知 , 选项 -n 必须与编辑指令一起配合 , 否则无法获得结果。例如 , 印出 white.dat 档内含有 "white"

       字串的资料行 , 其命令如下:

     

           sed -n -e '/white/p' white.dat  

     

    上面命令中 , 选项 -n 与编辑指令 /white/p (参照[section4.6]) 一起配合控制输出。其中 , 选项 -n 将输出控制权

    移给编辑指令;/white/p 将资料行中含有 "white" 字串印出萤幕。

     

    SED 手册 - 3.

    http://phi.sinica.edu.tw aspac@phi.sinica.edu.tw (2001-07-29 13:05:00)

     

       一般在实际使用编辑器的过程中 , 常需要执行替换文件中的字串、搬移、删除、与搜寻资料行等等动作。

       当然 , 一般交谈式编辑器( viemacs)都能做得到上述功能 , 但文件一旦有大量上述编辑需求时 ,

       用它们编辑十分没有效率。本章将用举例的方式说明如何用 sed 自动执行这些编辑功能。此外 , 在本章

       例中 , 均以下述方式描述文件的需求 :

                将文件中...资料 , 执行...(动作)

     

    如此 , 目的是为了能将它们迅速的转成编辑指令。其中 , " ...资料" 部份 , 转成指令中的位址参数表示 ;

    "执行...动作" 部份 , 则转成函数参数表示 。另外 , "执行...动作" 要由数个函数参数表示时 , 则可利

    "{ " " }" 集合这些函数参数([9]) , 其指令形式如下 :

             位址参数{

                     函数参数1

                     函数参数2

                     函数参数3

                         .

                         :

                      }

     

    上述指令表示 , 将对符合位址参数的资料 , 依次执行函数参数1、函数参数2、函数参数3 ... 表示的动作。

    下面各节 , 分别举例说明 sed 替换资料、移动、删除资料、及搜寻资料的命令。

    3.1 替换文件中的资料

    3.2 搬动文件中的资料

    3.3 删除文件中的资料

    3.4 搜寻文件中的资料

    查看(550) 评论(0) 收藏 分享 管理

  • apache的配置文档最全解析

    2008-10-21 10:33:35

    最近工作内容用到了apache,在里面配置很多的东西。但是不少东西问同事,他们都不知道。
    只好把httpd.conf文件打印了一份,昨天晚上看到了深夜1点。

    还有不少东西里面介绍的不全,只好去apache的网站搜索了。结果发现,里面的内容真的是很全。我很满意。
    也推荐给大家。呵呵。
    最近公司遭殃了。我在短短的两个星期内,已经打印了将近一百页的内容了。
    因为我发现每天晚上回去需要等车,在等车的十几分钟,坐车的二十几分钟里,可以看完大约十页的资料。
    就把白天重要的资料打印出来了。每天路上看一些。晚上在家里也看看。
    感觉对自己学习进步挺大的。





    http://www.uplinux.com/download/doc/apache/ApacheManual/



    Apache HTTP服务器 2.0版本文档


  • sed的替换操作

    2008-10-10 11:20:37

    让我们看一下 sed 最有用的命令之一,替换命令。使用该命令,可以将特定字符串或匹配的规则表达式用另一个字符串替换。下面是该命令最基本用法的示例:

    $ sed -e 's/foo/bar/' myfile.txt

    上 面的命令将 myfile.txt 中每行第一次出现的 'foo'(如果有的话)用字符串 'bar' 替换,然后将该文件内容输出到标准输出。请注意,我说的是每行第一次出现,尽管这通常不是您想要的。在进行字符串替换时,通常想执行全局替换。也就是说, 要替换每行中的所有出现,如下所示:

    $ sed -e 's/foo/bar/g' myfile.txt

    在最后一个斜杠之后附加的 'g' 选项告诉 sed 执行全局替换。

    关于 's///' 替换命令,还有其它几件要了解的事。首先,它是一个命令,并且只是一个命令,在所有上例中都没有指定地址。这意味着,'s///' 还可以与地址一起使用来控制要将命令应用到哪些行,如下所示:

    $ sed -e '1,10s/enchantment/entrapment/g' myfile2.txt

    上例将导致用短语 'entrapment' 替换所有出现的短语 'enchantment',但是只在第一到第十行(包括这两行)上这样做。

    $ sed -e '/^$/,/^END/s/hills/mountains/g' myfile3.txt

    该例将用 'mountains' 替换 'hills',但是,只从空行开始,到以三个字符 'END' 开始的行结束(包括这两行)的文本块上这样做。

    关于 's///' 命令的另一个妙处是 '/' 分隔符有许多替换选项。如果正在执行字符串替换,并且规则表达式或替换字符串中有许多斜杠,则可以通过在 's' 之后指定一个不同的字符来更改分隔符。例如,下例将把所有出现的 /usr/local 替换成 /usr:

    $ sed -e 's:/usr/local:/usr:g' mylist.txt

    在该例中,使用冒号作为分隔符。如果不指定分隔符,则变成了如下:

    $ sed -e 's/usr/local/usrg' mylist.txt

    这样就不能执行了
    如果需要在规则表达式中指定分隔符字符,可以在它前面加入反斜杠。


    规则表达式混乱
    目前为止,我们只执行了简单的字符串替换。虽然这很方便,但是我们还可以匹配规则表达式。例如,以下 sed 命令将匹配从 '<' 开始、到 '>' 结束、并且在其中包含任意数量字符的短语。下例将删除该短语(用空字符串替换):

    $ sed -e 's/<.*>//g' myfile.html

    这 是要从文件除去 HTML 标记的第一个很好的 sed 脚本尝试,但是由于规则表达式的特有规则,它不会很好地工作。原因何在?当 sed 试图在行中匹配规则表达式时,它要在行中查找最长的匹配。在我的前一篇 sed 文章中,这不成问题,因为我们使用的是 'd' 和 'p' 命令,这些命令总要删除或打印整行。但是,在使用 's///' 命令时,确实有很大不同,因为规则表达式匹配的整个部分将被目标字符串替换,或者,在本例中,被删除。这意味着,上例将把下行:

    <b>This</b> is what <b>I</b> meant.

    变成:
    meant.
    我们要的不是这个,而是:
    This is what I meant.

    幸运的是,有一种简便方法来纠正该问题。我们不输入“'<' 字符后面跟有一些字符并以 '>' 字符结束”的规则表达式,
    而只需输入一个“'<' 字符,后面跟有任意数量非 '>' 字符,并以 '>' 字符结束”的规则表达式。这将与最短、而不是最长的可能性匹配。新命令如下:

    $ sed -e 's/<[^>]*>//g' myfile.html

    在上例中,'[^>]' 指定“非 '>'”字符,其后的 '*' 完成该表达式以表示“零或多个非 '>' 字符”。对几个 html 文件测试该命令,将它们管道输出 "more",然后仔细查看其结果。


    更多字符匹配
    '[ ]' 规则表达式语法还有一些附加选项。要指定字符范围,只要字符不在第一个或最后一个位置,就可以使用 '-',如下所示:

    QUOTE:
    '[a-x]*'
    这将匹配零或多个全部为 'a'、'b'、'c'...'v'、'w'、'x' 的字符。另外,可以使用 '[]' 字符类来匹配空格。以下是可用字符类的相当完整的列表:

    字符类 描述
    [] 字母数字 [a-z A-Z 0-9]
    [] 字母 [a-z A-Z]
    [] 空格或制表键
    [] 任何控制字符
    [] 数字 [0-9]
    [] 任何可视字符(无空格)
    [] 小写 [a-z]
    [] 非控制字符
    [] 标点字符
    [] 空格
    [] 大写 [A-Z]
    [] 十六进制数字 [0-9 a-f A-F]

    尽可能使用字符类是很有利的,因为它们可以更好地适应非英语 locale(包括某些必需的重音字符等等).


    高级替换功能
    我们已经看到如何执行简单甚至有些复杂的直接替换,但是 sed 还可以做更多的事。实际上可以引用匹配规则表达式的部分或全部,并使用这些部分来构造替换字符串。作为示例,假设您正在回复一条消息。下例将在每一行前面加上短语 "ralph said: ":

    $ sed -e 's/.*/ralph said: &/' origmsg.txt

    输出如下:

    ralph said: Hiya Jim, ralph said: ralph said:
    I sure like this sed stuff! ralph said:

    该例的替换字符串中使用了 '&' 字符,该字符告诉 sed 插入整个匹配的规则表达式。因此,可以将与 '.*' 匹配的任何内容(行中的零或多个字符的最大组或整行)插入到替换字符串中的任何位置,甚至多次插入。这非常好,但 sed 甚至更强大。


    那些极好的带反斜杠的圆括号
    's///' 命令甚至比 '&' 更好,它允许我们在规则表达式中定义区域,然后可以在替换字符串中引用这些特定区域。作为示例,假设有一个包含以下文本的文件:

    foo bar oni eeny meeny miny larry curly moe jimmy the weasel

    现在假设要编写一个 sed 脚本,该脚本将把 "eeny meeny miny" 替换成 "Victor eeny-meeny Von miny" 等等。要这样做,首先要编写一个由空格分隔并与三个字符串匹配的规则表达式。

    '.* .* .*'

    现在,将在其中每个感兴趣的区域两边插入带反斜杠的圆括号来定义区域:

    '\(.*\) \(.*\) \(.*\)'

    除了要定义三个可在替换字符串中引用的逻辑区域以外,该规则表达式的工作原理将与第一个规则表达式相同。下面是最终脚本:

    $ sed -e 's/\(.*\) \(.*\) \(.*\)/Victor \1-\2 Von \3/' myfile.txt

    如您所见,通过输入 '\x'(其中,x 是从 1 开始的区域号)来引用每个由圆括号定界的区域。输入如下:

    Victor foo-bar Von oni Victor eeny-meeny Von miny Victor larry-curly Von moe Victor jimmy-the Von weasel

    随着对 sed 越来越熟悉,您可以花最小力气来进行相当强大的文本处理。您可能想如何使用熟悉的脚本语言来处理这种问题 -- 能用一行代码轻易实现这样的解决方案吗?


    组合使用
    在开始创建更复杂的 sed 脚本时,需要有输入多个命令的能力。有几种方法这样做。首先,可以在命令之间使用分号。例如,以下命令系列使用 '=' 命令和 'p' 命令,'=' 命令告诉 sed 打印行号,'p' 命令明确告诉 sed 打印该行(因为处于 '-n' 模式)。

    $ sed -n -e '=;p' myfile.txt

    无 论什么时候指定了两个或更多命令,都按顺序将每个命令应用到文件的每一行。在上例中,首先将 '=' 命令应用到第 1 行,然后应用 'p' 命令。接着,sed 继续处理第 2 行,并重复该过程。虽然分号很方便,但是在某些场合下,它不能正常工作。另一种替换方法是使用两个 -e 选项来指定两个不同的命令:

    $ sed -n -e '=' -e 'p' myfile.txt

    然而,在使用更为复杂的附加和插入命令时,甚至多个 '-e' 选项也不能帮我们的忙。对于复杂的多行脚本,最好的方法是将命令放入一个单独的文件中。然后,用 -f 选项引用该脚本文件:

    $ sed -n -f mycommands.sed myfile.txt

    这种方法虽然可能不太方便,但总是管用。


    一个地址的多个命令
    有时,可能要指定应用到一个地址的多个命令。这在执行许多 's///' 以变换源文件中的字和语法时特别方便。要对一个地址执行多个命令,可在文件中输入 sed 命令,然后使用 '{ }' 字符将这些命令分组,如下所示:

    1,20{         s/[Ll]inux/GNU\/Linux/g         s/samba/Samba/g         s/posix/POSIX/g }

    上例将把三个替换命令应用到第 1 行到第 20 行(包括这两行)。还可以使用规则表达式地址或者二者的组合:

    1,/^END/{         s/[Ll]inux/GNU\/Linux/g         s/samba/Samba/g         s/posix/POSIX/g         p }

    该例将把 '{ }' 之间的所有命令应用到从第 1 行开始,到以字母 "END" 开始的行结束(如果在源文件中没发现 "END",则到文件结束)的所有行。


    附加、插入和更改行
    既然在单独的文件中编写 sed 脚本,我们可以利用附加、插入和更改行命令。这些命令将在当前行之后插入一行,在当前行之前插入一行,或者替换模式空间中的当前行。它们也可以用来将多行插入到输出。插入行命令用法如下:

    i\ This line will be inserted before each line

    如果不为该命令指定地址,那么它将应用到每一行,并产生如下的输出:

    This line will be inserted before each line line 1 here
    This line will be inserted before each line line 2 here
    This line will be inserted before each line line 3 here
    This line will be inserted before each line line 4 here

    如果要在当前行之前插入多行,可以通过在前一行之后附加一个反斜杠来添加附加行,如下所示:

    i\ insert this line\ and this one\ and this one\ and, uh, this one too.

    附加命令的用法与之类似,但是它将把一行或多行插入到模式空间中的当前行之后。其用法如下:

    a\ insert this line after each line.  Thanks! :)

    另一方面,“更改行”命令将实际替换模式空间中的当前行,其用法如下:

    c\ You're history, original line! Muhahaha!

    因为附加、插入和更改行命令需要在多行输入,所以将把它们输入到一个文本 sed 脚本中,然后通过使用 '-f' 选项告诉 sed 执行它们。使用其它方法将命令传递给 sed 会出现问题。
  • vi操作命令大全2

    2008-10-10 10:54:48

    vi编辑器有3种模式:命令模式、输入模式、末行模式。掌握这三种模式十分重要:

      命令模式:vi启动后默认进入的是命令模式,从这个模式使用命令可以切换到另外两种模式,同时无论在任何模式下只要按一下[Esc]键都可以返回命令模式。在命令模式中输入字幕“i”就可以进入vi的输入模式编辑文件。

      输入模式:在这个模式中我们可以编辑、修改、输入等编辑工作,在编辑器最后一行显示一个“--INSERT--”标志着vi进入了输入模式。当我们完成修改输入等操作的时候我们需要保存文件,这时我们需要先返回命令模式,在进入末行模式保存。

      末行模式:在命令模式输入“:”即可进入该模式,在末行模式中有好多好用的命令。

    4.编辑操作
      进入输入模式命令
      i插入命令 a附加命令 o打开命令 c修改命令
      r取代命令 s替换命令 Esc退出命令

      输入模式的操作
      Home光标到行首
      End 光标到行尾
      Page Up和Page Down上下翻页
      Delect删除光标位置的字符

      删除操作(命令模式使用)
      x删除光标处的单个字符
      dd删除光标所在行
      dw删除当前字符到单词尾包括空格的所有字符
      #x例如3x删除光标处向右的三个字符
      #dd例如3dd从当前行开始向下删除三行文本

      撤销操作
      u命令取消最近一次的操作,可以使用多次来恢复原有的操作
      U取消所有操作
      Ctrl+R可以恢复对使用u命令的操作

      复制操作
      yy命令复制当前整行的内容到vi缓冲区
      yw复制当前光标所在位置到单词尾字符的内容到vi缓存区,相当于复制一个单词
      y$复制光标所在位置到行尾内容到缓存区
      y^复制光标所在位置到行首内容到缓存区
      #yy例如:5yy就是复制5行
      #yw例如:2yw就是复制两个单词

      如果要复制第m行到第n行之间的内容,可以在末行模式中输入m,ny例如:3,5y复制第三行到第五行内容到缓存区。

    5.查找和替换
      vi的查找和替换功能主要在末行模式完成:

      至上而下的查找
      / 要查找的字符窜,其中/代表从光标所在位置起开始查找,例如:/ work

      至下而上的查找
      ?要查找的字符窜 例如:/ work

      替换
      :s/old/new用new替换行中首次出现的old
      : s/old/new/g 用new替换行中所有出现的old
      :#,# s/old/new/g用new替换从第#行到第#行中出现的old
      :% s/old/new/g用new替换整篇中出现的old

      如果替换的范围较大时,在所有的命令尾加一个c命令,强制每个替换需要用户进行确认,例如:s/old/new/c 或s/old/new/gc

      6恢复文件
      vi在编辑某一个文件时,会生成一个临时文件,这个文件以 . 开头并以 .swp结尾。正常退出该文件自动删除,如果意外退出例如忽然断电,该文件不会删除,我们在下次编辑时可以选择一下命令处理:

      O只读打开,不改变文件内容
      E继续编辑文件,不恢复.swp文件保存的内容
      R将恢复上次编辑以后未保存文件内容
      Q退出vi
      D删除.swp文件
      或者使用vi -r 文件名来恢复未保存的内容

    在GUI下:
    (1)可按i进入插入模式
    (2)使用鼠标拖动反选要粘贴的内容,按鼠标左键复制选定块到缓冲区
    (3)然后将光标移到要粘贴处,按鼠标中键(两键鼠标可同时按左右键),粘贴缓冲区内容。

    在纯文本终端下:
    (1)选定文本块,使用v进入可视模式;移动光标键选定内容
    (2)复制选定块到缓冲区,用y;复制整行,用yy
    (3)剪切选定块到缓冲区,用d;剪切整行用dd
    (4)粘贴缓冲区中的内容,用p

    在同一编辑窗打开第二个文件,用:sp [filename]
    在多个编辑文件之间切换,用Ctrl+w

    命令前面加数字表示重复次数,加字母表示使用的缓冲区名称。
    获取帮助,用:help [内容或命令]

  • vi操作命令大全

    2008-10-08 11:33:51

    转自chinaunix。不错的站。最近用的比较多。还不是很熟悉。
    有机会学习一下。

    vi FileName 打开文件 FileName,并将光标置于第一行首。
    vi +n FileName 打开文件 FileName,并将光标置于第 n 行首。
    vi + FileName 打开文件 FileName,并将光标置于最后一行。
    vi + /pattern File 打开文件 File,并将光标置于其中第一个于 pattern 匹配的字符串处。
    vi –r FileName 在上次正用 vi 编辑 FileName 发生系统崩溃后,恢复FileName。
    vi File1 … Filen 打开多个文件,依次对之进行编辑。
    :%!xxd 按十六进制查看当前文件
    :%!xxd -r 从十六进制返回正常模式
    :n1,n2 co n3 将 n1 行到 n2 行之间的内容拷贝到第 n3 行下。
    :n1,n2 m m3 将 n1 行到 n2 行之间的内容移至第 n3 行下。
    :n1,n2 d 将 n1 行到 n2 行之间的内容删除。
    :n1,n2 w filename 将 n1 行到 n2 行之间的内容保存到文件 filename 中
    :n1,n2 w! Command 将文件中n1行到n2行的内容作为 Command的输入并执行之,
    若不指定 n1、n2,则将整个文件内容作为 Command 的输入。
    :r! Command 将命令Command 的输出结果放到当前行。
    :nr <文件> 把<文件>插入到第n行
    :so <文件> 读取<文件>,再执行文件里面的命令(文件中的命令应该都是一些ex命令)
    :l1,l2w <文件> 把第l1和第l2行之间的文本写到<文件>中去
    :w >> <文件> 添加到<文件>末尾. 也可以使用行号
    :e! 重新编辑当前文件,忽略所有的修改
     
    ·(、[、、]、)对应显示
    % 显示当前(、[、{ 、}、] 、)的对应项
    ) 显示对应的(
    ) 显示对应的[
    ] 显示对应的{

    ·(、[、、]、)内数据选择
    daB 删除{}及其内的内容 (在非v可视模式下)
    diB 删除{}中的内容
    ab 选择()中的内容
    ib 选择()中的内容( 不含() )
    aB 选择{}中的内容
    iB 选择{}中的内容( 不含{} )
    ·语法提示与自动补齐
    ★ <C-N><C-P> 插入模式下的单词自动完成
    ★ <C-X><C-L> 行自动完成(超级有用)
    ·设置ctags
    #ctags -f /usr/share/vim/vim63/funcs.tags -R /opt/j2sdk/src /usr/src/kernels/2.6.9-5.EL-i686
    ^p 自动补齐上下文已有相近项
    ^n 自动补齐~/.tags中的相近函数
    ^[ 显示~/.tags中的光标下的函数的原型,
    按^t退出函数
    :pta 函数名 预览窗口快速打开相应函数所在文件,并将光标定位在对应函数的开头
    K 显示光标下的C函数的man说明手册
    ·变量定位
    gd 转到光标下局部变量的定义处
    Gd 转到光标下全局变量的定义处

    ·编译选项
    :cn 命令会把你带到下一个出错地点,而不考虑它在什么文件里。
    :cc 命令会向你显示当前错误的编译器输出信息;
    :cl 会生成一个列有项目所有错误的列表,以供浏览这些错误
     
    3]光标移动
    ·字符
    h 光标左移一个字符。
    l 光标右移一个字符。
    ·字
    w 或 W 光标右移一个字至字首。
    B 或 b 光标左移一个字至字首。
    E 或 e 光标右移一个字至字尾。
    ·句} 光标移至句尾。
    ( 光标移至句首。
    ·段) 光标移至段落开头。
    { 光标移至段落结尾。
    ·行k 或 Ctrl+p 光标上移一行。
    j 或 Ctrl+n 光标下移一行。
    Enter 光标下移一行。
    nG 光标移至第 n 行首。
    n+ 光标下移 n 行。
    n- 光标上移 n 行。
    n$ 光标移至第 n 行尾。
    0 光标移至当前行首。
    $ 光标移至当前行尾。
    ·屏幕
    H 光标移至屏幕顶行。
    M 光标移至屏幕中间行。
    L 光标移至屏幕最后行。
    Ctrl+u 向文件首翻半屏。
    Ctrl+d 向文件尾翻半屏。
    Ctrl+f 向文件尾翻一屏。
    Ctrl+b 向文件首翻一屏。
    nz 将第 n 行滚至屏幕顶部。不指定 n 时将当前行滚至屏幕顶。
    4}插入
    # 在文件中插入行号(不是显示行号,是插入!)
    ★:g/^/exec "s/^/".strpart(line(".")." ", 0, 4)
    ·光标
    i 在光标前插入。
    a 在光标后插入。
    ·行
    I 在当前行首插入。
    A 在当前行尾插入。
    o 在当前行之下一新行插入。
    O 在当前行之上新开一行插入。
     
    5)替换
    r 替换当前字符。
    R 替换当前字符及其后的字符,直至按 ESC 键。
    s 从当前光标位置处开始,以输入的文本代替指定数目的字符。
    S 删除指定数目的行,并以所输入的文本代替。
    6)修改
    ncw 或 nCW 修改指定数目的字符。
    nCC 修改指定数目的行。
    :r filename 将文件 filename 插入在当前行之下
    7)查找替换
    /<C-R><C-W> 把狭义单词 <cword> 写到 搜索命令 行
    /<C-R><C-A> 把广义单词 <cWORD> 写到 搜索命令 行
    :g/str/s/str1/str2/g
    第一个g表示对每一个包括s1的行都进行替换,
    第二个g表示对每一行的所有进行替换
    包括str的行所有的str1都用str2替换
    :%s/f $/for$/g 将每一行尾部的“f ”(f键和空格键)替换为for
    :%s/^/mv /g 在每一行的头部添加“mv ”(mv键和空格键)
    :s/fred/<c-r>a/g 替换fred成register a中的内容,呵呵

    :g/<input|<form/p 显示含<input或<form的行

    # 替换一个visual区域
    # 选择一个区域,然后输入 :s/Emacs/Vim/ 等等,vim会自动进入:模式
    :'<,'>s/Emacs/Vim/g 前面的'<,'>是vim自动添加的

    # 在多个文档中搜索
    :bufdo /searchstr
    :argdo /searchstr
     

    复制与剪切
    xp 交换前后两个字符的位置
    ddp 上下两行的位置交换
    :g/fred/t$ 拷贝行,从fred到文件末尾(EOF)
     
    9)窗口操作
    :vne [filename]
    :sp [filename]
    :S [filename]
    :new [filename]
    :^w + ^r 交换两个窗口的位置
    ^w = 窗口等宽
    :res -n 窗口高度减小n
    :res +n 窗口高度增大n
    :vert res -n
    :vert res +n
    10)DOS格式文本转成Unix格式文本
    :1,$s/^M//g
    11)书签
    在阅读和编写大的程序文件时,利用标记(书签)功能定位是十分有帮助的。
    将光标移到想做标记的位置。假如做一个名为“debug1”的标记,那么用户可在命令模式下输入做标记的命令“mdebug1”,然后敲入回车键,一个名为“debug1”的标记就做好了。
    接下来用户可以随意将光标移到其它的位置,当在命令模式下输入“`debug1”后,就能快速回到“debug1”的标记所在行的行首。

    12)删除操作
    :%s/r//g 删除DOS方式的回车^M
    :%s= *$== 删除行尾空白
    :%s/^(.*)n1/1$/ 删除重复行
    :%s/^.pdf/new.pdf/ 只是删除第一个pdf
    :%s/<!--_.-->// 又是删除多行注释(咦?为什么要说「又」呢?)
    :g/^s*$/d 删除所有空行
    :g!/^dd/d 删除不含字符串'dd'的行
    :v/^dd/d 同上 (译释:v == g!,就是不匹配!)
    :g/str1/,/str2/d 删除所有第一个含str1到第一个含str2之间的行

    :v/./.,/./-1join 压缩空行
    :g/^$/,/./-j 压缩空行
    ndw 或 ndW 删除光标处开始及其后的 n-1 个字符。
    d0 删至行首。
    d$ 删至行尾。
    ndd 删除当前行及其后 n-1 行。
    x 或 X 删除一个字符。
    Ctrl+u 删除输入方式下所输入的文本。
    ^R 恢复u的操作
    J 把下一行合并到当前行尾
    V 选择一行
    ^V 按下^V后即可进行矩形的选择了
    aw 选择单词
    iw 内部单词(无空格)
    as 选择句子
    is 选择句子(无空格)
    ap 选择段落
    ip 选择段落(无空格)
    D 删除到行尾
    x,y 删除与复制包含高亮区
    dl 删除当前字符(与x命令功能相同)
    d0 删除到某一行的开始位置
    d^ 删除到某一行的第一个字符位置(不包括空格或TAB字符)
    dw 删除到某个单词的结尾位置
    d3w 删除到第三个单词的结尾位置
    db 删除到某个单词的开始位置
    dW 删除到某个以空格作为分隔符的单词的结尾位置
    dB 删除到某个以空格作为分隔符的单词的开始位置
    d7B 删除到前面7个以空格作为分隔符的单词的开始位置
    d) 删除到某个语句的结尾位置
    d4) 删除到第四个语句的结尾位置
    d( 删除到某个语句的开始位置
    d) 删除到某个段落的结尾位置
    d{ 删除到某个段落的开始位置
    d7{ 删除到当前段落起始位置之前的第7个段落位置
    dd 删除当前行
    d/text 删除从文本中出现“text”中所指定字样的位置,
    一直向前直到下一个该字样所出现的位置(但不包括该字样)之间的内容
    dfc 删除从文本中出现字符“c”的位置,一直向前直到下一个该字符所出现的位置(包括该字符)之间的内容
    dtc 删除当前行直到下一个字符“c”所出现位置之间的内容
    D 删除到某一行的结尾
    d$ 删除到某一行的结尾
    5dd 删除从当前行所开始的5行内容
    dL 删除直到屏幕上最后一行的内容
    dH 删除直到屏幕上第一行的内容
    dG 删除直到工作缓存区结尾的内容
    d1G 删除直到工作缓存区开始的内容
    修改命令操作
    r 更改当前字符
    cw 修改到某个单词的结尾位置
    c3w 修改到第三个单词的结尾位置
    cb 修改到某个单词的开始位置
    cW 修改到某个以空格作为分隔符的单词的结尾位置
    cB 修改到某个以空格作为分隔符的单词的开始位置
    c7B 修改到前面7个以空格作为分隔符的单词的开始位置
    c0 修改到某行的结尾位置
    c} 修改到某个语句的结尾位置
    c4} 修改到第四个语句的结尾位置
    c( 修改到某个语句的开始位置
    c) 修改到某个段落的结尾位置
    c{ 修改到某个段落的开始位置
    c7{ 修改到当前段落起始位置之前的第7个段落位置
    ctc 修改当前行直到下一个字符c所出现位置之间的内容
    C 修改到某一行的结尾
    cc 修改当前行
    5cc 修改从当前行所开始的5行内容
    . 重复上一次修改!

    13}Set 选项设置
    set all 列出所有选项设置情况。
    set term 设置终端类型。
    set ignorecase 在搜索中忽略大小写。
    set list 显示制表位(^I)和行尾标志($)。
    set number 显示行号。
    set showmode 示用户处在什么模式下
    set report 显示由面向行的命令修改国的行数目。
    set terse 显示简短的警告信息。
    set warn 在转到别的文件时,若没有保存当前文件则显示 No write 信息。
    set autowrite 在“:n”和“:!”命令之前都自动保存文件
    set nomagic 允许在搜索模式中,使用前面不带\的特殊字符。
    set nowrapscan 禁止 vi 在搜索到达文件两端时,又从另一端开始。
    set mesg 允许 vi 显示其他用户用 write 写到自己终端上的信息。
    autoindent (ai) noai 使新行自动缩进,和上(下)行的位置对齐
    autoprint (ap) ap 每条命令之后都显示出修改之处
    autowrite (aw) noaw 在:n,:!命令之前都自动保存文件
    beautify (bf) nobf 在输入的时候忽略所有的控制字符(除了制表键(tab),换行(newline),进纸(formfeed))
    directory= (dir=) /tmp 存放缓冲区的目录名
    edcompatible noedcompatible 在替换的时候使用类ed的用法
    errorbells (eb) errorbells 出错的时候响铃
    exrc (ex) noexrc 允许在主目录(home)外面之外放.exrc文件
    hardtabs= (ht=) 8 设置硬制表的边界
    ignore case (ic) noic 正规式里忽略大小写
    lisp nolisp 打开lisp模式
    list nolist 显示所有的制表键和行的结尾
    magic agic 可以使用更多的正规表达式
    mesg mesg 允许向终端发送消息
    number (nu) nonumber 显示行号
    open open 允许开放和可视化
    optimize (opt) optimize 优化吞吐量,打印时不发回车
    paragraphs= (para=) IPLPPPQPPLIbp 设置{ & }的分界符
    prompt prompt 命令模式下的输入给出:的提示符
    readonly (ro) noro 除非用!号否则不准保存文件
    redraw noredraw 当编辑的时候重绘屏幕
    remap remap 允许宏指向其他的宏
    report= 5 如果影响的行数>这个数的话就报告
    scroll 1/2 window 下卷屏幕时滚动屏幕的数目, 同样这也是z命令输出的行数(z 输出2倍滚屏的大小)
    sections= SHNHH HU 定义节的末尾(当使用命令[[ 和 ]] 时)
    shell= (sh=) /bin/sh 缺省的SHELL,如果设置了环境变量SHELL的话,就使用变量
    shiftwidth= (sw=) 8 当使用移动(shift)命令时移动的字符数
    showmatch (sm) nosm 显示{, }, (, ), [, 或者 ] 的匹配情况
    showmode noshowmode 显示你处在什么模式下面
    slowopen (slow) 插入之后不要立刻更新显示
    tabstop= (ts=) 8 设置制表停止位(tabstop)的长度
    taglength= (tl=) 0 重要标记的字符个数(0表示所有的字符)
    tags= tag, /usr/lib/tags 定义包含标记的文件路径
    term= 设置终端类型
    terse noterse 显示简短的错误信息
    timeout (to) timeout 一秒钟后键盘映射超时
    ttytype= 设置终端类型
    warn warn 显示"No write since last change"信息
    window= (w=) 可视模式下窗口的行数
    wrapmargin= (wm=) 0 右边距,大于0的话最右边的单词将折行,留出n个空白位置
    wrapscan (ws) ws 查找到文件尾后再重头开始
    writeany (wa) nowa 可以保存到任意一个文件去
    14}特殊字符
    ^ 匹配字符串位于行首。
    $ 匹配字符串位于行尾。
    . 用在模式串中,表示任何单个字符。
    在命令模式下,重复上次的命令。
    * 在模式串中,表示其前字符可出现任意多次。
    [] 用在模式串中,表示指定方位内字符,其中可用-表示一个字
    符范围,用^表示不在某个范围内的字符。
    ESC 从插入状态转换到命令状态
    ^[ 功能同 ESC
    15]大小写转换
    guu 行小写
    gUU 行大写
    g~~ 行翻转(当然指大小写啦)
    guw 字小写(狭义字) 译注:建议对比iw
    gUw 字大写(狭义字)
    g~w 字翻转(狭义字)
    vEU 字大写(广义字)
    vE~ 字翻转(广义字)
    ggguG 把整个文章全部小写(ft!bt!)
    16) 跳转足迹'. 跳到最后修改的那一行 (超级有用)(ft,怎么又是这个评价)
    `. 不仅跳到最后修改的那一行,还要定位到修改点
    <C-O> 依次沿着你的跳转记录向回跳 (从最近的一次开始)
    <C-I> 依次沿着你的跳转记录向前跳
    :ju(mps) 列出你跳转的足迹
    17)命令历史
    :history 列出历史命令记录
    :his c 命令行命令历史
    :his s 搜索命令历史
    q/ 搜索命令历史的窗口
    q 命令行命令历史的窗口
    :<C-F> 历史命令记录的窗口
    18]寄存器
    # 列出寄存器(Registers)
    :reg 显示所有当前的registers
    "1p 表示引用register,1表示一个名字叫做1的register,p就是粘贴(paste)命令
    译释:
    "也用来定义register
    先输入 ",表示定义register
    然后输入名字,如0~9,a~z
    然后执行删除或复制命令,如dd或y,
    或者是visual模式下的d(删除选中的部分)或y(复制选中的部分)
    则被删除或复制的部分就被存入了这个命名的register
    观察:一个特殊的register, "" ,里面存储了一个匿名的删除/复制
    在你执行dd或y的时候,被作用的部分被存到了""中
    19}命令行
    "ayy@a把当前行作为一个Vim命令来执行
    译释:"ayy 是定义当前行到register a,然后@a是执行register a中存储的指令
    10yy copy 当前行以下10行
    11} 排序
    :%!sort -u 使用sort程序排序整个文件(用结果重写文件)
    !1) sort -u 排序当前段落 (只能在normal模式下使用!!)
    :.,+5!sort 排序当前行及以下5行
    20) 列操作
    :%s= [^ ]+$=&&= 复制最后一列
    :%s= f+$=&&= 一样的功能
    :%s= S+$=&& ft,还是一样
    :s/(.*).*)/2"1/ 颠倒用:分割的两个字段
    :%s(w+s+))str1:1str2: 处理列,替换所有在第三列中的str1
    :%sw+)(.*s+)(w+)$:321: 交换第一列和最后一列 (共4列)

    ·.vimrc
    " Use Vim settings, rather then Vi settings (much better!).
    set nocompatible
    "c风格的缩进
    :set expandtab "不使用tab只使用空格
    :set cindent shiftwidth=4
    "自动缩进
    :set ai

    "语法
    ":set filetype=java
    :set syntax=java
    "键入)、] 、},显示(、[、{
    :set showmatch
    "手工定义折叠
    :set foldmethod=manual

    "标签文件位置
    set tags=/usr/share/vim/vim63/funcs.tags
    "在插入模式下通过按[Ctrl]N自动地将任何类、方法或者字段名补齐
    set complete+=k
    " 不要用声音烦我!
    set visualbell
    "历史
    :set history=50
    "显示行列位置
    :set ruler
    "设置字符编码
    set fileencodings=gb2312
    "set encoding=euc-cn
    "设置ruler
    set ruler
    "显示当前命令
    set showcmd
    "incsearch
    set incsearch
    " allow backspacing over everything in insert mode
    set backspace=indent,eol,start
    "自动检测文件类型
    :filetype on

    """""""""""快捷键定义"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    if version >= 600
    "查找
    "map <C-H> /
    "查找函数原型
    map <C-H> yiw/^\(\s\)*\(sub\)\|\(function\)\(\s\)*<C-r>"<CR>
    "继续查找
    map <F3> n

    "使用<F10>显示类、属性、方法列表
    map <F2> :Tlist<CR>
    " 用compiler定义的编译程序来编译当前程序
    "map <F9> :make "%"<CR>
    "使用<F11>来进行php语法检测
    map <F11> :!php -l "%" <CR>
    map ;w :call FormatText()<CR>
    "查找当前光标下的字
    map <F4> /<C-R><C-W><CR>
    endif
    """""""""""::快捷键定义"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    """""""""""格式化文件"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    function FormatText()
    :%s/\t/ /g "把\t换成4个空格
    :%s/ *$//g "去掉行尾空格
    endfunction
    """""""""""格式化文件"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     
    """"""""""显示行尾的tab和多余空格"""""""""""""""""""""""""""""""""""""""""""""""
    set listchars=tab:>-,trail:~
    set list
    syntax match Trail " +$"
    highlight def link Trail Todo
    """"""""""::显示行尾的tab和多余空格"""""""""""""""""""""""""""""""""""""""""""""
    function LastMod()
    if line("$") > 5
    let l = 5
    else
    let l = line("$")
    endif
    exe "1," . l . "/CnsProgCMTime/s/CnsProgCMTime .*/CnsProgCMTime " . strftime("%Y-%m-%d %H:%M:%S")."/e"
    endfunction
    "map <F5> :call LastMod()<CR>
    """""""""""自动加注释的*星号""""""""""""""""""""""""""""""""""""""""""""""""""""
    "使用如/* ... */ 的注释时,r在插入模式下回车时插入* ;
    "o 在普通模式下,使用 "o" 或 "O" 时插入*
    :set formatoptions=tcro
    """""""""""::自动加注释的*星号""""""""""""""""""""""""""""""""""""""""""""""""""
     
    vi扩展的正则表达式
    | 指示交替,如home|house 指匹配home或house
    () 用于分组,如home|house可以写为ho(me|use)
    *可以用到()上(home|house)* 可以匹配home, homehouse,househome, homehousehomehouse
    \(...\) 实际匹配的文本可以使用、等在替换命令的替换部分进行检索
    + 可匹配正则表达式的一次或多次出现,既可以是单个字符也可以是()或\(...\)括起的内容,至少匹配一次
    ho(use|me)+ 指至少是house或home不允许是空
    ? 指前面正则表达式的零次或一次出现,表示出现或未出现。如free?d 将匹配fred或freed除此不能匹配其他文本

    定义区间表达式。区间表达式描述了表示重复次数的计数数字。 同\
    (home|house) 只能匹配homehome, homehouse, househome, househouse
     

    编译相关
    ·用编译器来编译 当前文件
    :!perl -c %
    :!php -l % 用php来检查错误
    :!php -q % 用php来运行程序

    ·编译当前程序为a.out并执行该./a.out
    :!gcc % -o a.out && ./a.out
    执行结果
    old umask is %#0
    new umask is %#0
    ·编译错误信息
    :cl! 列出所有错误信息的详细列表
    :cl 列出当前条错误信息
    :cn 列出下一条错误信息
    :cp 列出上一条错误信息

    :cnew 最新错误信息条数
    :cold 旧的错误信息条数
    :cwin 或 :copen 打开错误信息窗口
    :cclose 关闭上面打开的信息窗口
     
    自动补齐
    CTRL-X CTRL-F 文件名
    CTRL-X CTRL-L 整行
    CTRL-X CTRL-D 宏定义 (并搜索所包含的文件)
    CTRL-X CTRL-I 当前文件以及所包含的文件
    CTRL-X CTRL-K 词典文件内的单词
    CTRL-X CTRL-T 近义词词典文件内的单词
    CTRL-X CTRL-] 标记
    CTRL-X CTRL-V Vim 命令行
     
    C程序设计
    gd 反色显示光标下局部标识符串的所有出现,并转到第一次出现处。
    gD 反色显示光标下全局标识符串的所有出现,并转到第一次出现处。
    --------------------------------------------------------------------------------------
    :checkpath 列出所有include的头文件
    --------------------------------------------------------------------------------------
    [i 显示函数定义
    extern __mode_t umask (__mode_t __mask) __THROW;
    --------------------------------------------------------------------------------------
    [+CTRL+i 跳转到[i所标识的函数定义处
    --------------------------------------------------------------------------------------[I 列出当前文件及包含文件内的含有当前字符的行
    --------------------------------------------------------------------------------------[d 显示由#define所定义的标识符的定义语句
    printf(|tom);
    #define tom "yaoshuyin"
    --------------------------------------------------------------------------------------
    CTRL+] 跳转到光标当前位置的标签处 (例如:一个函数的定义)。
    CTRL+T 跳转到执行 CTRL-] 命令前的地方。
    :tselect 从一连串匹配的标签中选出一个。
    [/ 跳转到注释开始的位置。
    ]/ 跳转到注释结束的位置。
    ----------------------------------------------------------------
    [# 返回到未闭合的 #if, #ifdef, or #else 处。
    ]# 前进到未闭合的 #else 或 #endif 处。
    [( 返回到未闭合的 '(' 处。
    )) 前进到未闭合的 ']' 处。
    [{ 跳转到最近对应的 '{' 处。
    }} 跳转到最近对应的 ']' 处。

    ·字符集和进制转换
    ga 显示光标处字符的ascii,hex,oct,...晕菜的一堆转换
    如 s 前按ga
    <s> 115, Hex 73, Octal 163
    列块操作
    <C-V>选中列块
    I<string><ESC> 在块的每一行首加上string
    A<string><ESC> 在块的每一行尾加上string
    C<string><ESC> 修改选中的列块(即删除并输入新内容 )
    c<string><ESC> 修改选中的列块(即删除并输入新内容 )
    > 左移Tab宽度
    vimrc中的文件名及路径
    如在D:\cnscnprogrames\Vim\vim63\下编辑 vi tmp\file.java (即D:\cnscnprogrames\Vim\vim63\tmp\file.java)

    expand("%") #tmp\file.java
    expand("%:p") #D:\cnscnprogrames\Vim\vim63\tmp\file.java
    expand("%:h") #tmp
    expand("%:t") #file.java
    expand("%:e") #java
    expand("%:t:r") #file
    expand("%:r") #tmp\file
     

    ·一个简单编译器(编译、执行常见程序)
    #vi ~/.vimrc
    "定义F9来编译、执行程序
    map <F9> :call ProgCompileRun() <CR>
    func ProgCompileRun()
    "save the current file first
    :w
    "取得程序后缀名 如javaphp pl py
    let ext = expand("%:e")
    "编译Java
    if ext == "java"
    if expand("%:h") != ""
    :!javac % && java -classpath expand("%:h") %:t:r
    else
    :!javac % && java %:t:r
    endif
    return
    endif
    "执行php
    if ext == "php"
    :!php %
    return
    endif
    "编译执行c/cc/cpp
    if ext == "c" || ext == "cc" || ext == "cpp"
    :!gcc % -o a.out && ./a.out
    return
    endif
    "编译执行perl
    if ext == "pl"
    :!perl -c %
    return
    endif
    "编译执行python
    if ext == "py"
    :!python %
    return
    endif

    endfunc

  • vim帮助

    2008-09-15 18:52:41

    http://linux.chinaitlab.com/manual/newsoft/vi/doc/help.html

    这是it实验室的资料,那个站点真的不错,资料真的很全。

    最近换行去做性能测试了,主要是linux下的测试。需要补习这方面的知识。


    类别:Linux 查看评论

    Link URL: http://hi.baidu.com/sihanjishu/blog/item/f2fa04ec890ec22162d09f2e.html
  • linux bash shell编程基础

    2008-09-15 18:52:41

    通常情况下,我们从命令行输入命令每输入一次就能够得到系统的一次响应。一旦需要我们一个接着一个的输入命令而最后才得到结果的时候,这样的做法显然就没有效率。要达到这样的目的,通常我们利用shell程序或者shell脚本来实现。

      一、简介

      Shell编程有很多类似C语言和其他程序语言的特征,但是又没有编程语言那样复杂。Shell程序就是放在一个文件中的一系列Linux命令和实用程序,在执行的时候,通过Linux一个接着一个地解释和执行每个命令。

      下面我们来看一个简单的shell程序:

      1、首先建

    阅读全文
    类别:Linux 查看评论

    Link URL: http://hi.baidu.com/sihanjishu/blog/item/c21a150e23f6f5e136d12223.html
392/2<12
Open Toolbar