zoukankan      html  css  js  c++  java
  • Linux之sed,awk(流编辑器)

    sed:  s----substitute(替换)

    1. 文本替换(使用-i选项,可以将结果应用于原文件

    many people在进行替换之后,借助重定向来保存文件(未使用-i选项):

    $ sed  's/text/replace_text/' file > newfile

    $ mv newfile file

    landen@landen-Lenovo:~/文档$ cat apacheLog.txt
    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom1.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"
    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom2.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    landen@landen-Lenovo:~/文档$ sed -i 's/tom/sam/' apacheLog.txt
    landen@landen-Lenovo:~/文档$ cat apacheLog.txt
    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /sam1.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"
    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /sam2.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    landen@landen-Lenovo:~/文档$ sed -i 's/sam[[:digit:]].dat/tom.txt/' apacheLog.txt
    landen@landen-Lenovo:~/文档$ cat apacheLog.txt
    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom.txt HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"
    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom.txt HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    上面的sed命令只是将每一行中第一处符合样式的内容替换掉。But如果要替换所有内容,so需要在命令尾部加上参数g. 其方法如下:

    landen@landen-Lenovo:~/文档$ cat apacheLog.txt | sed -i 's/sam.dat/tom.arff/' apacheLog.txt
    landen@landen-Lenovo:~/文档$ cat apacheLog.txt
    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"
    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    landen@landen-Lenovo:~/文档$ cat apacheLog.txt | sed -i 's/tom.txt/sam.dat/g' apacheLog.txt
    landen@landen-Lenovo:~/文档$ cat apacheLog.txt
    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /sam.dat sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"
    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /sam.dat sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

           But Sometimes不需要替换前N处匹配,而是需要替换剩下的匹配。有一个选项可以用来忽略前N处匹配,并从第N+1处开始替换,即 /Ng,如下:

    landen@landen-Lenovo:~/文档$ cat apacheLog.txt | sed -i 's/tom.arff/sam.dat/2g' apacheLog.txt
    landen@landen-Lenovo:~/文档$ cat apacheLog.txt
    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"
    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    2. 移除空白行 (d----delete(移除)

    apachelog.txt文件内容如下(两行间有空行):

    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"

    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    landen@landen-Lenovo:~/文档$ sed '/^$/d' apacheLog.txt (未使用-i选项,即未应用于原文件)
    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"
    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    3. 已匹配字符串标记&

    在sed中,用&标记匹配样式的字符串,thus,就能够在替换字符串时use已匹配的内容

    landen@landen-Lenovo:~/文档$ sed 's/w+/[&]/g' apacheLog.txt (未使用-i选项,即未应用于原文件)

    [125].[226].[150].[44] – - [[21]/[Jul]/[2012]:[01]:[12]:[56] +[0800]] "[GET] /[tom].[arff] [sam].[dat] [HTTP]/[1].[1]" [200] [8092] "-" "[Mozilla]/[4].[0] ([compatible]; [MSIE] [8].[00]; [Windows] [7])"

    [125].[226].[151].[42] – - [[21]/[Jul]/[2012]:[01]:[15]:[56] +[0800]] "[GET] /[tom].[arff] [sam].[dat] [HTTP]/[1].[1]" [200] [8092] "-" "[Mozilla]/[4].[0] ([compatible]; [MSIE] [7].[00]; [Windows] [7])"

    4. 子串匹配标记 1,2 (后向引用)

    apacheLog.txt原内容如下:

    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"

    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 200 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    &代表匹配给定样式的字符串,but我们可以用后向引用 1,2 匹配给定样式的其中一部分(括号内),如下:

    landen@landen-Lenovo:~/文档$ sed 's/200 ([0-9]+)/1/' apacheLog.txt (其中1表示8092)

    125.226.150.44 – - [21/Jul/2012:01:12:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 8092 "-" "Mozilla/4.0 (compatible; MSIE 8.00; Windows 7)"

    125.226.151.42 – - [21/Jul/2012:01:15:56 +0800] "GET /tom.arff sam.dat HTTP/1.1" 8092 "-" "Mozilla/4.0 (compatible; MSIE 7.00; Windows 7)"

    5. 组合多个表达式

    sed 'expression1' | 'expression2' 等价于 sed ' expression1; expression2 '

    6. 引用

    sed表达式通常用单引号来引用。不过亦可以用双引号,双引号会通过对表达式求值来对其进行扩展。当想在sed表达式中使用一些变量字符串时,双引号就有用武之地了,如下:

    landen@landen-Lenovo:~/文档$ text=hello
    landen@landen-Lenovo:~/文档$ echo hello world | sed "s/$text/HELLO/"
    HELLO world

    awk:被设计用于数据流,可对列和行进行操作。In addition, awk有很多内建的功能,such as 数组,函数等

    awk脚本的结构基本如下所示:

    awk ‘BEGIN{ print "start" } pattern { commands } END{ print "end" }'

    从上之,一个awk脚本通常由3部分组成: BEGIN语句块,END语句块和能够使用模式匹配的通用语句块。这3个语句块是可选的,它们中任何一个部分都可以不出现在脚本中。脚本通常会被包含在单引号或双引号中

    工作方式如下所示:

    1》 执行BEGIN { commands } 语句块中的语句;

    2》从文件或stdin中读取一行,然后执行pattern { commands } . 重复这个过程(类似while循环),直到文件全部被读取完毕(默认执行{ print } , 即打印每一个读取到的行。awk对于读取到每一行,都会执行这个语句块);

    3》当读至输入流 (input stream) 末尾时,执行END { commands } 语句块

    例如:

    landen@landen-Lenovo:~/文档$ echo -e "line1 line2" | awk 'BEGIN{ print "Start" } { print } END{ print "END" }'
    Start
    line1
    line2
    END

    当使用不带参数的print时,它会打印出当前行。

    Note: 1. 当print的参数是以逗号进行分割时,参数打印时则以空格作为定界符

             2. 在awk的print语句中,双引号是被当做拼接操作符使用的。

    例如:

    landen@landen-Lenovo:~/文档$ echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }'
    v1 v2 v3
    landen@landen-Lenovo:~/文档$ echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"-"var2"-"var3; }'
    v1-v2-v3

    1. awk中的特殊变量

    NR: 表示记录数量(number of records), 在执行过程中对应于当前行号;

    NF: 表示字段数量(number of fields), 在执行过程中对应于当前行的字段数;

    $0:  这个变量包含执行过程中当前行的文本内容;

    $1:  这个变量包含第一个字段的文本内容;

    $2:  这个变量包含第二个字段的文本内容。

    2. 将外部变量值传递给awk

    借助选项-v,可以将外部值(并非来自stdin)传递给awk,例如:

    landen@landen-Lenovo:~/文档$ VAR=love

    landen@landen-Lenovo:~/文档$ echo | awk -v VARIABLE=$VAR '{ print VARIABLE }'
    love
    In addition, 有一种灵活的方式可以将多个外部变量传递给awk,给变量赋值时,只能用分号或空格隔开例如:

    landen@landen-Lenovo:~/文档$ var1="I"; var2="Love"; var3="You"
    landen@landen-Lenovo:~/文档$ echo | awk '{ print v1,v2,v3}' v1=$var1 v2=$var2 v3=$var3
    I Love You
    landen@landen-Lenovo:~/文档$ vari1="I" vari2="Love" vari3="You"
    landen@landen-Lenovo:~/文档$ echo | awk '{ print v1,v2,v3}' v1=$vari1 v2=$vari2 v3=$vari3
    I Love You
    注意:awk最后的v1,v2,v3之间只能用空白隔开,不能有“ ;,”等其它符号隔开,否则只会获取第一个;左边最近的值,如下:

    landen@landen-Lenovo:~/文档$ vari1="I" vari2="Love" vari3="You"
    landen@landen-Lenovo:~/文档$ echo | awk '{ print v1,v2,v3}' v1=$vari1;v2=$vari2;v3=$vari3

    3. 用getline读取行

    landen@landen-Lenovo:~$ echo -e "I Love You" | awk 'BEGIN { getline; print "Read ahead first line", $0 } { print $0 }'
    Read ahead first line I
    Love
    You

    4. 用样式对awk处理的行进行过滤

    $ awk ' NR < 5 ' # 行号小于5的行

    $ awk ' NR==1,NR==4 ' # 行号在1到5之间的行

    $ awk ' /linux/ ' # 包含样式linux的行可用正则表达式来指定样式

    $ awk ' !/linux/ ' # 不包含样式linux的行

    5. 从awk中读取命令输出

     landen@landen-Lenovo:~/文档$ echo | awk '{ "grep o testfile" | getline cmdout ; print cmdout }'

     Love

    6. 设置字段定界符

    -F "delimiter"

    7. 在awk中使用循环

  • 相关阅读:
    z-index
    点击按钮跳转带指定的位置
    导航-角
    弹出框
    控制叠加风格
    Python学习三
    玩转HTTP
    http-关于application/x-www-form-urlencoded等字符编码的解释说明
    Python学习二
    git merge 和 git rebase
  • 原文地址:https://www.cnblogs.com/likai198981/p/3279590.html
Copyright © 2011-2022 走看看