• 1. Shell 高级编程Ch11 Shell高级编程
  • 2. 主要内容11.1 正则表达式 11.2 grep:正则搜索并打印 11.3 awk:处理数据并生成报告 11.4 sed:流编辑器
  • 3. 示例1eg1:如果记录以n或s开头,就打印这个记录。 grep:grep ‘^[ns]’ eg1 awk:awk '/^[ns]/{print}' eg1 sed:sed –n ‘/^[ns]/p’ eg1
  • 4. 11.1.1 正则表达式介绍使用s h e l l时,从一个文件中抽取多于一个字符串将会很麻烦。例如,在一个文本中抽取一个词,它的头两个字符是大写的,后面紧跟四个数字。如果不使用某种正则表达式,在s h e l l中将非常难实现这个操作。
  • 5. 11.1.1 正则表达式介绍正则表达式是一种可以用于模式匹配和替换的强大工具,我们可以在很多unix程序中找到正则表达式的身影,例如vi,perl,php,awk,sed,emacs,grep等。 正则表达式常见的应用场合是验证用户输入是否合法,例如:验证邮件地址是否符合“xxx@xxx.xxx”的模式,其中x字符是字母,数字,下划线,小数点或减号,邮件地址的每一部分可以有一个或多个x字符。 再比如验证IP地址时候符合“yyy.yyy.yyy.yyy”的模式
  • 6. 11.1.1 基本字符^ 匹配行首 $ 匹配行尾 * 一个单字符后紧跟*,匹配0个或多个此单字符 [ ] 匹配[ ]内字符。可以是一个单字符,也可以是字符序列。可以使用-表示[ ]内字符序列范围,如用[ 1 - 5 ]代替[ 1 2 3 4 5 ] \ 用来屏蔽一个元字符的特殊含义。因为有时在s h e l l中一些元字符有特殊含义。\可以使其失去应有意义 . 匹配任意单字符 p a t t e r n \ { n \ } 用来匹配前面p a t t e r n出现次数。n为次数 p a t t e r n \ { n,\ } 含义同上,但次数最少为n p a t t e r n \ { n,m \ } 含义同上,但p a t t e r n出现次数在n与m之间
  • 7. 11.1.2 练习1ex1: 1.打印所有以a开头的行 2.打印所有以a开头、包含数字的行 3.打印所有以a开头、后面只包含数字或不含任何字符的行grep ‘^a’ ex1grep ‘^a.*[0-9].*’ ex1grep ‘^a[0-9]*\b’ ex1
  • 8. 11.2 grep相信grep是UNIX和LINUX中使用最广泛的命令之一。grep(全局正则表达式版本)允许对文本文件进行模式查找。如果找到匹配模式, grep打印包含模式的所有行。grep支持基本正则表达式,也支持其扩展集。grep有三种变形,即: grep:标准grep命令,本章大部分篇幅集中讨论此格式。 egrep:扩展grep,支持基本及扩展的正则表达式,与之相对应的一些更加规范的模式,这里也不予讨论。 fgrep:fast (fixed) grep。允许查找字符串而不是一个模式。单词fast,是不是比grep速度要快?
  • 9. 11.2.1 grepgrep一般格式为: grep [选项]基本正则表达式[文件] 这里基本正则表达式可为字符串。 在grep命令中输入字符串参数时,最好将其用单引号或双引号括起来。例如:‘m y s t r i n g’。这样做有两个原因,一是以防被误解为s h e l l命令,二是可以用来查找多个单词组成的字符串。 shell 对单引号里的内容不转义,对双引号里的内容转义,shell处理后在给grep,例如:grep “\\\\” datafile 等价于 grep ‘\\’ datafile
  • 10. 11.2.1 grep选项常用的grep选项有: -c 只输出匹配行的计数。 -i 不区分大小写。 -h 查询多文件时不显示文件名。 -l 查询多文件时输出包含匹配字符的文件名。 -n 显示匹配行及行号。 -s 不显示不存在或无匹配文本的错误信息。 -v 显示不包含匹配文本的所有行。
  • 11. 11.2.2 常用正则表达式举例^行首$行尾[Ss]igna[Ll]匹配单词signal、signaL、Signal、SignaL\(man\|MAY\)包含may的大写或小写的行^USER$只包含USER的行tty$以tty结尾的行\.带句点的行.*00之前(或之后)有任意字符000*连续两个以上0^the以the开头的行
  • 12. [Ii]I或i[Ii][Nn]IN、In、iN或in^$空行^.*$匹配行中任意字符串[a-zA-Z]任意字母[a-z][a-z]*至少一个字母^……$包含6个字符的行[^0-9\$]非数字及美元符号[^0-9a-zA-Z]非数字及字母[123]1至3中一个数字[Dd]eviceDevice 或 deviceDe..ce前两个字母为De,后面跟两个任意字符,最后为ce11.2.2 常用正则表达式举例
  • 13. 常用正则表达式举例\^q以^q开头的行^.$仅有1个字符的行^\.[0-9]\{2\}以一个句点和两个数字开头的行[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\}*日期[0-9]\{3\}. [0-9]\{3\}. [0-9]\{3\}. [0-9]\{3\}*IP地址11.2.2 常用正则表达式举例
  • 14. 11.2.3 示例2eg2 找出文件中邮件中合法的邮箱地址; 找出126或163或gmail邮箱地址: grep '[a-zA-Z0-9\.-_]*@[a-zA-Z0-9\.-_]*\.[a-zA-Z0-9\.-_]*' eg2grep '[a-zA-Z0-9\.-_]*@\(gmail\|126\|163\)\.com]*' eg2
  • 15. 11.2.3 示例3eg3 找出126或163或gmail邮箱总共的行数 找出126或163或gmail邮箱并显示其行数 找出当前目录下所有包含126邮箱的文件grep –c '[a-zA-Z0-9\.-_]*@\(gmail\|126\|163\)\.com]*' eg2grep –n '[a-zA-Z0-9\.-_]*@\(gmail\|126\|163\)\.com]*' eg2grep –l '[a-zA-Z0-9\.-_]*@\(gmail\|126\|163\)\.com]*' *
  • 16. 11.2.4 练习ex2: 1. Print all lines containing the string San. 2. Print all lines where the person's first name starts with J. 3. Print all lines ending in 700. 4. Print all lines that don't contain 834. 5. Print all lines where birthdays are in December.
  • 17. 11.2.4 练习ex2: 6. Print all lines where the phone number is in the 408 area code. 7. Print all lines containing an uppercase letter, followed by four lowercase letters, a comma, a space, and one uppercase letter. 8. Print lines where the last name begins with K or k. 9. Print lines preceded by a line number where the salary is a six-figure number. 10. Print lines containing Lincoln or lincoln (remember that grep is insensitive to case).
  • 18. 11.3.1 awkawk命令,要格式化报文或从一个大的文本文件中抽取数据包。 整体来说, a w k是所有s h e l l过滤工具中最难掌握 复杂的语法 含义不明确的错误提示信息。
  • 19. 11.3.2 示例eg4 df | awk ‘{print $1 "\t\t" $5}’ 打印第一列和第五列,中间用两个Tab隔开
  • 20. 11.3.3 打印选择的域awk 中的 print 命令把输入文件中选择的数据输出。 当 awk 读取文件的一行,根据指定的 输入域分隔符 把行分开, FS,awk 的一个环境变量。它被预先定义为一个或者多个空格或者制表符。 变量 $1, $2, $3, ..., $N 把输入行的第一第二第三直到最后一个域保存起来。变量 $0 把整行的值保存起来。在下面的图片描述中,我们看到 df 命令输出有6栏。
  • 21. 11.3.3 输入域的分隔符域分隔符,既不是一个单独的字符也不是一个普通的表达式,是控制 awk 把一个输入分割成几个域。输入记录按分割定义进行字符顺序扫描;域就是在相符的那些文字中间的那部分。 域分隔符代表内建的变量 FS。 域分隔符变量的值可以在 awk 程序中用赋值操作符 = 来改变。通常最好的执行时间是一开始也就是还没有处理任何输入的时候,因此第一个记录就被随合适的分隔符一起读取。使用特殊的 BEGIN 。
  • 22. awk 'BEGIN { FS=":" } { print $1 "\t" $7 }' /etc/passwd 11.3.3 输入域的分隔符
  • 23. 11.3.4 示例eg5 awk 'BEGIN { FS=":" } { printf "username:%s\t",$1;printf "home:%s\n",$7}' /etc/passwd
  • 24. 11.4.1 sed命令sed是一个非交互性文本流编辑器。它编辑文件或标准输入导出的文本拷贝。标准输入可能是来自键盘、文件重定向、字符串或变量,或者是一个管道的文本。 使用sed实现的一个重要功能是在另一个系统中下载的文件中剔除控制字符 sed不修改源文件。除非使用重定向功能
  • 25. 11.4.2 定址定义:决定对哪些行进行编译 形式:数字或表达式(默认处理所有行) 数字代表行号;$指最后一行;m,n形式表似处理m行至n行 定址后可以打印、删除、修改等
  • 26. 11.4.2 定址eg sed ‘1,3d’
  • 27. 11.4.3 命令与选项
  • 28. 11.4.3 命令与选项n 不打印;s e d不写编辑行到标准输出,缺省为打印所有行(编辑和未编辑)。p命令可以用来打印编辑行。 例如: 1) cat test | sed ‘s/://g’ 使用s / : / / g删除:。 2) cat test | sed ‘/^$/d’ 使用/ ^ $ / d删除空行。 3) cat test | sed ‘$d’ 使用$ d删除最后一行 4) cat test | sed ‘1d’ 使用1 d删除第一行。
  • 29. 11.4.4 示例
  • 30. 11.4.5 练习