sed,awk

Linux shell编程从初学到精通

最近工作时遇到了一个问题,就是查看进行时,只查看某些进行的进程号,若直接用ps aux|grep sms 这样会得到一大堆的东东,所以同事推荐用awk,同
时也提及了sed。

这里抽时间对这两个命令做一个总结,仅为个人学习工作所用。

##sed、awk是什么?

它们是linux\unix系统中的两种功能强大的文本处理工具。
  • 有一个sed的编辑器,才有了sed(stream editor)这个名字,它是一个将一系列编辑命令作用于一个文本文件的理想工具。
  • 由于创建awk的三个作者名称 是Aho、Weinberger和Kernighan,所以得名为AWK,是一种能够对结构化数据进行操作并产生格式化报表的编程语言。

##sed的使用

###使用场合

  • 编辑相对交互式广西编辑器而言太大的文件
  • 编辑命令太复杂,在交互式文本编辑器中难以输入的情况
  • 对文件扫描一遍,但是需要执行多个编辑函数的情况

sed只对缓冲区中的原始文件的副本进行编辑,并不编辑原始的文件。so,若要保存个性后的文件,压根将输出重定向到另一个文件。如:

sed 'sed command' source-file > target-file

###调用方式
如何没有指定输入文件sed将从标准输入中接受输入

  • 在shell命令行输入命令调用sed,格式为:

    sed [option] ‘sed command’ 输入文件
    注意此处为单引号将命令引起来

  • 将sed命令插入脚本文件后,然后通过sed命令调用它,格式为:

    sed [option] -f sed脚本文件 输入文件

  • 将sed命令插入脚本文件后,最常用的方法是设置该脚本文件为可执行,然后直接执行该脚本,格式为:

    ./sed脚本文件 输入文件

但此命令脚本文件,应该以sha-bang(#!)开头,sha-bang后面是解析这个脚本的程序名。

####sed命令选项及其意义

  • -n:不打印所有行到标准输出
  • -e:将下一个字符串解析为sed编辑命令,如果只传递一个编辑命令给sed,-e选项可以省略
  • -f:表示正在调用sed脚本文件

###命令组成方式

定位文本行和编辑命令两部分组成

####定位文本

  • 使用行号,指定一行,或指定行号范围
  • 使用正则表达式

下面是sed命令定位文本的方法

  • x 为指定的行号
  • x,y 指定行号范围
  • /pattern/ 查询包含模式的行
  • /pattern/pattern/ 查询包含两个模式的行
  • /pattern/,x 从与模式匹配到x号行之间的行 反之类似
  • x,y!查询不包括x和y行号的行

####常用编辑命令

  • p 打印匹配行
  • = 打印文件行号
  • a\ 在定位行号之后追加文本信息
  • i\ 在定们行号之前插入文本信息
  • d 删除定位行
  • c\ 用新文本替换定位文本
  • s 使用替换模式替换相应模式
  • r 从另一个文件中读广西
  • w 将文本写入到一个文件
  • y 变换字符
  • q 第一个模式匹配完成后退出
  • l 显示与八进制ASCII码等价的控制字符
  • {} 在定位行执行的命令组
  • n 读取下一个输入行,用下一个命令处理新的行
  • h 将模式缓冲区的文本复制到保持缓冲区
  • H 将模式缓冲区的文本追加到保持缓冲区
  • x 互换模式缓冲区和保持缓冲区的内容
  • g 将保持缓冲区的内容复制到模式缓冲区
  • G 将保持缓冲区的内容追加到模式缓冲区

###实例
我们就用下面这个文件内容作为事例参考:

#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test.settings")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

-n 选项的使用

  • 使用-n 不输出所有的内容 1p 输出第一行
➜  linuxstudy  sed -n '1p' manage.py2
#!/usr/bin/env python
  • 打印3到6行
➜  linuxstudy  sed -n '3,6p' manage.py2
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test.settings")
  • 模式匹配
➜  linuxstudy  sed -n '/environ/p' manage.py2
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test.settings")

- e 选项的使用

  • 打印行号:
    ➜  linuxstudy  sed -n '/env/=' manage.py2
    1
    6

添加e选项:

    ➜  linuxstudy  sed -n -e '/env/p' -e '/env/=' manage.py2 
    #!/usr/bin/env python
    1
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test.settings")
    6

    `sed不支持多个编辑命令的用法,带多个编辑命令的用法,一般格式为:`

    sed [option] -e 编辑命令 -e 编辑命令 ... -e 编辑命令 输入文件

    将下面命令操作存放到一个后缀为.sed的文件中,让其可执行
    #!/usr/bin/sed -f 
    /command/a\
    we append a new line

sed文本定位

  • 匹配元字符 $和.
    ➜  linuxstudy  sed -n '/\./p' manage.py2
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test.settings")
        from django$.core.management import execute_from_command_line
        execute_from_command_line(sys.argv)
    ➜  linuxstudy  sed -n '/\$/p' manage.py2
        from django$.core.management import execute_from_command_line
  • 元字符进行匹配
    $在正则中表示行尾,但在这里表示最后一行
    sed的基本命令,可以放在单引号外或内都行,根据自己的习惯
    ➜  linuxstudy  sed  '$p' manage.py2 得取最后一行

    ➜  linuxstudy sed  -n '/.*line/p' manage.py2 找出以line结尾的行
  • ! 符号,表示取反,但是不能用于模式匹配的取反

      ➜  linuxstudy  sed -n '2,4!p' manage.py2 不打印2到4行 
  • 使用行号与关键字匹配限定行范围

      /pattern/,x和x,/pattern/ 这两种形式其实与x,y一样的,只是将x或y代替罢了
    
      ➜  linuxstudy  sed -n '4,/mana/p' manage.py2  得到的是从第四行起到与mana匹配的行的内容
    
      if __name__ == "__main__":
          os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hwbuluo.settings")
    
          from django$.core.management import execute_from_command_line

sed文本编辑

  • 插入文本 i\

      在匹配行的前端插入
      sed '定位i\text' 文件
    
      修改上面的追加脚本:
      #!/usr/bin/sed -f 
      /command/i\
      we append a new line
  • 修改文本 modify.sed c\

      -------------------
      #!/usr/bin/sed -f
    
      /command/c\
      I modify the file.
      -------------------
    
      执行:./modify.sed
  • 删除文本 d 与追加和插入修改有所不同,这里在后面不需要添加\

      sed '1,3d' manage.py2
  • 替换文本 替换文本与修改文本类似,只是修改是对一整行的个性,替换则是对局部进行修改

      s/被替换的字符串/新字符串/[替换选项]
    
      替换选项及意义:
          g:替换文本中所有出现被替换字符串之处,若不使用此选项,则只替换每行的第一个匹配上的字符串
          p:与-n选项结合,只打印替换行
          w 文件名:表示将输出定向到一个文件
    
      ➜  linuxstudy  sed -n 's/command/============/p' manage.py2 
          from django$.core.management import execute_from_============_line
          execute_from_============_line(sys.argv)
    
      也可以 linuxstudy  sed -n 's/command/============/2p' manage.py2   来替换每行出现的第几个 

##awk的使用

###使用场合
###调用方式
###实例

awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;};END {for (i=0;i<NR;i++) print i,name[i]}'   /etc/passwd

0 root
1 daemon
2 bin
3 sys
4 sync
5 games
6 man
7 lp
8 mail

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is",size/1024/1024 ,"M"}'

[end]size is 0.098505 M