zoukankan      html  css  js  c++  java
  • awk、sed处理文件的简单例子

      awk、sed对处理日志文件和写shell脚本时非常有益。这个东西,如果不经常操作,真心过一段时间就忘差不多。。要掌握熟练,就要多练习,这没什么可说的。

    awk '条件{命令}' filename

    假设一个待处理的文件test是这样的:

    比如我需要第一列是tcp的,并打印出第4列和第6列

      awk '/^tcp/ {print $4," ",$6}' test

     或者 awk '$1 == "tcp" {print $4," ",$6}' test

    比如我想在刚才打印的两列上边,写个头。比如4列头是aaa,6列头是bbb。4列尾是ccc,6列尾是ddd

      awk 'BEGIN {print "aaa"," ","bbb"} /^tcp/ {print  $4," ",$6} END {print "ccc"," ","ddd"}' test

    第二列显然没对齐,可以使用类似于C语言的printf格式化输出。

    值得注意的是,awk是以文件每一行进来处理的。

    不难发现,语法中单引号里头,都是按照"条件+{动作}"这种格式来的。

    比如BEGIN是条件, {print "aaa"," ","bbb"}是动作;BEGIN是在文件处理第一行开始前先执行的。

    /^tcp/ 是条件,{print  $4," ",$6}是动作;

    END是条件,{print "ccc"," ","ddd"}是动作。END是在文件处理结束以后,执行的。

    当一个动作{A}前边紧接着还是个{动作X},就意味着A这个动作没有条件,就是指什么条件都可以。

    awk中几个内置变量很常用。F表示字段,域,是Field...

    比如FS是分隔符号,NR是awk读取的记录数(awk是一行一行的读取),NF是读取的列数

    NR:number of records  原文件记录的第几行数

    NF:number of fields   该行记录的总列数

    举个例子:用户文件/etc/passed是以冒号分隔的

    awk '{FS=":"}{print $1," ",$2}' /etc/passwd | head -n10

    发现第一行并没有得到我们想要的效果。这是因为{FS=":"}这个命令前边并没有条件限制,而此时awk已经把第一行读完了。所以如此。

    这里就需要在{FS=":"}这个命令的前边加上BEGIN关键字就好了。

    还有很多例子...

    前边的NR、NF是awk的内置变量。awk也可以自定义变量,awk编程。

    比如上边的/etc/passwd中有多少个用户(也是多少行...)并且输出每个用户名

    利用awk编程实现可以这样:

    # awk -F ':'  '{num++; print $1;}  END {print 'total is ', num}'

    { }中两个命令使用分号 ; 分隔。

    输出的分隔符,比如输出的列用逗号分割,利用OFS

    awk -F',' 'BEGIN{OFS=","} {print $2,$6,$9}'  xx.log

    再举个例子:找出文件xxx.txt中不是以#开头的所有行

    awk '{if($1!~/^#/) print $0}' xxx.txt 

     

    sed的命令( stream editor 流编辑器),同样是对行的处理。注意匹配什么

    s是替换,重点是匹配什么。

    d是删除,用数字表示行,或者也利用匹配行

    i是行前插入

    a是行后追加

    c是替换整个行

    ===========---------------几个例子

    比如删除2到4行的内容

    sed '2,4d' filename

    sed '2,$d' filename   从第二行开始都删除

    sed '/^#/ d' filename #开头的行删除

    清除一个文件的空行

    sed '/^$/d' test.log > test1.log

    数字替换成xx 

    sed 's/[0-9]/xx/g' 

    替换8到10行的内容,把其中每行出现的udp替换成tcp

    sed '8,10s/udp/tcp/g' filename

    如果说只替换每行出现的第一个,这样写 

    sed 's/udp/tcp/1' filename

    在第一行插入字符串hehe,换行

    sed '1 i hehe' filename

    在原来的第2行到第4行上,都插入xxx

    sed '2,4 i xxx' filename

    在第2行后面追加字符串hi,换行

    sed '2 a hi' filename

    在原来的第2行到第4行上,都追加xxx  

    sed '2,4 a xxx' filename

    取出一个文件a.log的2到12行内容

    sed -n '2,12p'  a.log 

    推荐以下这几篇文章,很不错的哈:

    sed:

    http://coolshell.cn/articles/9104.html

    awk:

    http://coolshell.cn/articles/9070.html

    http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

    http://www.linuxsong.org/2010/09/awk-string-function/

    awk提供了许多强大的字符串函数,见下表:
    awk内置字符串函数

    gsub(r,s) 在整个$0中用s替代r
    gsub(r,s,t) 在整个t中用s替代r
    index(s,t) 返回s中字符串t的第一位置
    length(s) 返回s长度
    match(s,r) 测试s是否包含匹配r的字符串
    split(s,a,fs) 在fs上将s分成序列a
    sprint(fmt,exp) 返回经fmt格式化后的exp
    sub(r,s) 用$0中最左边最长的子串代替s
    substr(s,p) 返回字符串s中从p开始的后缀部分
    substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分

    比如应用一个

    awk -F'xxx' '{print substr($1,0,index($1," ")),substr($2,0,index($2,""")-1)}'
  • 相关阅读:
    c++之五谷杂粮4---explicit
    ping
    Swift常量和变量
    Swift数据类型简介
    Swift 注释
    Swift标示符以及关键字
    xcode简介
    认识Swift
    Android_adb详解
    详解Android AM命令
  • 原文地址:https://www.cnblogs.com/firstForEver/p/4978808.html
Copyright © 2011-2022 走看看