Linux上文本处理三剑客
grep:文本过滤(模式:pattern)工具;
- grep, egrep, fgrep
sed:stream editor,文本编辑工具;
awk:Linux上的实现gawk,文本报告生成器;
grep命令
作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行;
模式:由正则表达式字符及文本字符所编写的过滤条件;
REGEXP:由一类特殊字符及文本字符所编写的模式,其中有些字符不表示字符字面意义,而表示控制或通配的功能;
正则表达式引擎
使用方法:grep [OPTIONS] PATTERN [FILE...] # 指令 选项 正则引擎 文件
选项:
- --color=auto: 对匹配到的文本着色显示;
- -v: 显示不能够被pattern匹配到的行;
- -i: 忽略字符大小写;
- -o: 仅显示匹配到的字符串;
- -q: 静默模式,不输出任何信息;
- -A #:after, 后#行
- -B #: before, 前#行
- -C #:context, 前后各#行
- -E:使用ERE;
字符匹配:
- .: 匹配任意单个字符;
- []: 匹配指定范围内的任意单个字符
- [^]:匹配指定范围外的任意单个字符
- [:digit:]:任意数字,相当于0-9
- [:lower:]:任意小写字母
- [:upper:]: 任意大写字母
- [:alpha:]: 任意大小写字母
- [:alnum:]:任意数字或字母
- [:space:]:空格
- [:punct:]:标点符号
匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数;
bash的正则是贪婪模式:
- .*:任意长度的任意字符;
- \?:匹配其前面的字符0或1次;即前面的可有可无;
- \+:匹配其前面的字符至少1次;
- \{m\}:匹配前面的字符m次;
- \{m,n\}:匹配前面的字符至少m次,至多n次;
- \{0,n\}:匹配前面的字符至多n次;
- \{m,\}:匹配前面的字符至少m次;
位置锚定:
- ^:行首锚定;用于模式的最左侧;
- $:行尾锚定;用于模式的最右侧;
- ^PATTERN$: 用于模式匹配整行;
- ^$: 空行;
- ^[[:space:]]*$:任意长度的空格
- \< 或 \b:词首锚定;用于单词模式的左侧;
- \> 或 \b:词尾锚定;用于单词模式的右侧;
- \<PATTERN\>:匹配整个单词;
分组:
- \(\):将一个或多个字符捆绑在一起,当作一个整体进行处理;
- 例如:\(xy\)*ab
后项引用: 分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, ...
例如:
\1: 从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;
\(ab\+\(xy\)*\):
\1: ab\+\(xy\)*
\2: xy
1 练习: 2 1、显示/proc/meminfo文件中以大小s开头的行;(要求:使用两种方式) 3 # grep "^[s,S]" /proc/meminfo 4 # grep -i "s" /proc/meminfo -i 忽略大小写 5 6 2、显示/etc/passwd文件中不以/bin/bash结尾的行; 7 # grep -v "/bin/bash$" /etc/passwd -v 取反 8 9 3、显示/etc/passwd文件中ID号最大的用户的用户名; 10 # awk -F: '{if(a<$3){a=$3;user=$1}}END{print user}' /etc/passwd 11 # sort -t: -k3 -n /etc/passwd | tail -1 | cut -d: -fl 12 13 4、如果用户root存在,显示其默认的shell程序; 14 # id root &> /dev/null && grep "^root\>" /etc/passwd | cut -d: -f7 15 # 判断root存不存在,如果存在将它扔掉,然后执行正则匹配,然后切割取第7块(从1开始) 16 17 5、找出/etc/passwd中的两位或三位数; 18 # grep "\<[0-9]\{2,3\}\>" /etc/passwd 19 20 6、显示/etc/rc.d/rc.sysinit文件中,至少以一个空白字符开头的且后面存非空白字符的行; 21 # grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg 22 23 7、找出"netstat -tan"命令的结果中以'LISTEN'后跟0、1或多个空白字符结尾的行; 24 # netstat -tan | grep "LISTEN[[:space:]]*$" 25 26 8、添加用户bash、testbash、basher以及nologin(其shell为/sbin/nologin);而后找出/etc/passwd文件中用户名同shell名的行; 27 # grep "^\([[:alnum:]]\+\>\).*\1$" /etc/passwd
egrep及扩展的正则表达式
egrep = grep -E
命令格式:egrep [OPTIONS] PATTERN [FILE...]
扩展正则表达式的元字符:egrep相比grep只多了一个或者,其他的一样
字符匹配:
- .
- []
- [^]
次数匹配:
- *
- ?: 0或1次;
- +:1次或多次;
- {m}:匹配m次;
- {m,n}:至少m,至多n次;
锚定:
- ^
- $
- \<, \b
- \>, \b
分组:
- ()
- 后向引用:\1, \2, ...
或者:new***
- a|b
1 练习: 2 3 1、显示当前系统root、centos或user1用户的默认shell和UID; 4 5 # grep -E '^(root|centos|user1)\>' /etc/passwd | cut -d: -f1,3,7 6 7 2、找出/etc/rc.d/init.d/functions文件(centos6)中某单词后面跟一个小括号的行; 8 9 # grep -E -o "^[_[:alpha:]]+\(\)" /etc/rc.d/init.d/functions 10 11 3、使用echo输出一绝对路径,使用egrep取出其基名; 12 13 # echo "/mnt/sdc" | grep -E -o "[^/]+/?$" | cut -d"/" -f1 14 15 进一步地:使用egrep取出路径的目录名,类似于dirname命令的结果; 16 17 4、找出ifconfig命令结果中1-255之间的数值; 18 19 5、找出ifconfig命令结果中的IP地址;
fgrep:
不支持正则表达式搜索;