正则表达式
基本定义:
正则表达使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。简而言之,正则表达式就是处理字符串的方法,以行为单位进行字符串的处理,通过一些特殊符号的辅助,可以让用户轻松搜索/替换某特定的字符串。
正则表达式分为两类:基本的正则表达式和扩展的正则表达式。
linux基本命令grep egrep fgrep用法以及正则表达式
grep、egrep、fgrep命令
本文中主要介绍了linux系统下grep egrep fgrep命令和正则表达式的基本参数和使用格式、方法。
基本定义:
grep(global search regular RE ) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它只能使用基本的正则表达式来搜索文本,并把匹配的行打印出来。
grep是很常见也很常用的命令,它的主要功能是进行字符串数据的比较,然后符合用户需求的字符串打印出来,但是主意,grep在数据中查找一个字符串时,是以“整行”为单位进行数据筛选的。
egrep命令等同于grep -E,利用此命令可以使用扩展的正则表达式对文本进行搜索,并把符合用户需求的字符串打印出来。
fgrep命令等同于grep -F,它利用固定的字符串来对文本进行搜索,但不支持正则表达式的引用,所以此命令的执行速度也最快。fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。
fgrep “$name…[a-z]” file 就是在file里面找到和字符$name…[a-z]一样的行. 其中$和…等没有转义的意义.
用正则表达式一定要带上引号,这是一种固定格式,新手切记,博主刚开始学习是就动不动将两个混为一谈!
grep:能够接受正则表达式和通配符 格式: grep [option] pattern filename 注意: pattern如果是表达式或者超过两个单词的, 需要用引号引用. 可以是单引号也可双引号, 区别是单引号无法引用变量而双引号可以. -o:精确匹配 -v:反向输出 -c:统计匹配到行的数量而不是匹配的次数。 -b:计算一行中字符串的偏移量,起始值为0,一般与-o连用。 -n:显示匹配到的文件中的字符串的行数。 -R:对文本进行递归搜索。 -i:忽略大小写。 -e:匹配多个样式。 -q:静默模式,不显示匹配到的文件,使用$?查看是否匹配成功。 -A n:打印匹配某个结果之后的n行。 -B n:打印匹配某个结果之前的n行。 -C n:打印匹配某个结果前后的n行。 +:表示匹配前面的一个正则表达式一个或多个实例 其他用法: grep +文本 +文件名
基本正则表式的元字符:grep -E
字符匹配:
.: 任意单个字符
[]: 指定范围内的任意单个字符
[0-9], [[:digit:]]
[a-z], [[:lower:]]
[A-Z], [[:upper:]]
[[:alpha:]] :大小写字母
[[:alnum:]]:字母数字
[[:space:]]:空白字符(空格,制表符,换行)
[[:punct:]]:符号
[^]:指定范围外的任意单个字符
次数匹配:用来指定匹配其前面的字符的次数:
*: 任意次
.*: 匹配任意长度的任意字符
\?: 0次或1次
x\?y, xy, y, xxy
贪婪模式:尽可能的长的去匹配字符;
\{m\}: 匹配m次
\{m,n\}:m至n次
\{m,\}: 至少m次;
\{0,n\}:至多n次;
位置锚定:用于指定字符出现的位置:
^: 锚定行首 ^Char
$: 锚定行尾 char$
^$: 空白行
\
分组:
\(\):\(ab\)*xy
引用:
\1: 后向引用,引用前面的第一个左括号以及与之对应的右括号中的模式所匹配到的内容
\2:引用第二个匹配到的
扩展的正则表达式
扩展的正则表达只是在基本的正则表达上作出了小小的一点修改,其修改如下:
在扩展的正则表达中把\( \) 写成()、\{ \} 写成{ },另外加入了+:次数匹配,匹配其前面的字符至少出现一次,无上限、|: 或者(二取一),其余的都一样, 基本正则表达式,使用( ) { } . ? |都需要转义,在扩展正则表达中不需要加\,其详细信息如下:
egrep: 使用扩展正则表达来构建模式,相当于grep -E , 元字符:
字符匹配:
.: 任意单个字符
[]: 指定范围内的任意单个字符
[^]: 指定范围外的任意单个字符
次数匹配:
*:匹配其前面的字符任意次;
?: 匹配其前面的字符0或1次;
+: 匹配其前面的字符至少1次
{m}: 匹配其前面的字符m次;
{m,n}: 至少m次,至多n次
{m,}: 至少m次;
{0,n}:至多n次;
锚定:
^: 行首
$: 行尾
\<, \b: 词首 \>, \b:词尾
分组:
(): 分组
|: 或者, ac|bc
grep -E “con(C|c)at” :匹配 conC或cat
以下是乱用正则和通配符的结果: [root@localhost test]# ls | grep 'colou.r' #用正则 colouur "colouur" [root@localhost test]# ls | grep 'colou?r' #将通配符用于正则,两者混用了 [root@localhost test]# ls | grep colou?r #只用通配符了 colouur "colouur" 如果确保一定要用正则,可以这么用: [root@localhost test]# ls | grep 'colou\?r' #正则中对于特殊符号要转义 color colour [root@localhost test]# ls |grep -E 'colou?r' #-E表示使用扩展正则表达式 color colour [root@localhost test]# ls |egrep 'colou?r' #也可以使用默认正则表达式的grep的命令--egrep color colour 以上两条命令等效,都使用正则表达式。
在 info grep 的菜单:* Regluar Expressions:: ->Basic vs Extended:: 中写道:
3.6 Basic vs Extended Regular Expressions
=========================================
In basic regular expressions the meta-characters `?’, `+’, `{’, ‘ | ‘ , `(’, and `)’ lose
their special meaning; instead use the backslashedversions
`\?’, `\+’, `\{’, `\|’, `\(’, and `\)’ .
[root@localhost test]# echo asdasnot | grep -o -b 'not' #使用-o -b选项 5:not [root@localhost test]# echo -e "123\nasd\nqwe" |grep -n 'asd' #使用-n选项 2:asd [root@localhost ~]# grep 'asd' . -R -n #对文本进行递归搜索-R,用于查找源代码中的函数所在位置. ./.bash_history:100:cd dsd sad asdquitr ./.bash_history:112:echo asd|tee ./.bash_history:113:echo asd|tee - [root@localhost test]# ls |grep -e 'asd' -e 'co' #使用-e指定匹配多个样式 asd 1 asd 2 co col [root@localhost test]# echo "qwe" >a | grep 'qwe' a #grep 文本 文件名 qwe [root@localhost test]# seq 10 |grep 5 -A 3 #一下为打印某个匹配结果前后的n行 5 6 7 8 [root@localhost test]# seq 10 |grep 5 -B 3 2 3 4 5 [root@localhost test]# seq 10 | grep 5 -C 2 3 4 5 6 7 \(\):表示匹配与方括号中的正则表达式群 \n:匹配重复 \( \)内的字符出现的次数 \{n,m\} :匹配它前面的翻个字符出现的次数n-m次 [root@localhost test]# ls | grep '\(asd\).*\1' #匹配asd至少1次 asd9asd9 asdasd [root@localhost test]# ls |grep 'asd\{2,\}' #匹配asd至少两次 [root@localhost test]# ls 1.sh hello hello2 [root@localhost test]# echo "hello3" > hello2 [root@localhost test]# bash -x -c "ls |grep hell*" + grep hello hello2 #无单引号bash会预扩展,将hell*变为+ grep hello hello2 hello3 + ls [root@localhost test]# bash -x -c "ls |grep 'hell*' " + grep 'hell*' #不会预先扩展,直接匹配hell* + ls hello hello2 [root@localhost test]# bash -x -c 'ls |grep "hell*"' #单引号匹配文件名 + grep 'hell*' + ls hello hello2 [root@localhost test]# bash -x -c "ls |grep "hell*"" #双引号匹配文件内容 + grep hello hello2 + ls hello3 # '\w\+'表示匹配每一个单词 [root@localhost test]# echo -e "asd\n\nqwe\n\n123" | grep '\w\+' asd qwe 123 #使用+,匹配一个小写的单词 [root@localhost test]# echo "is GAY" | grep '\([a-z]\+\)' is GAY
一些小练习:
1、显示/proc/meminfo文件中以大小写s开头的行; # grep "^[sS]" /proc/meminfo # grep -i "^s" /proc/meminfo 2、取出默认shell为非bash的用户; # grep -v "bash$" /etc/passwd | cut -d: -f1 3、取出默认shell为bash的且其ID号最大的用户; # grep "bash$" /etc/passwd | sort -n -t: -k3 | tail -1 | cut -d: -f1 4、显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行; # grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit 5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行; # grep "^[[:space:]]\{1,\}[^[:space:]]\{1,\}" /boot/grub/grub.conf 6、找出/etc/passwd文件中一位数或两位数; # grep --color=auto "\<[0-9]\{1,2\}\>" /etc/passwd 7、找出ifconfig命令结果中的1到255之间的整数; # ifconfig | grep -E --color=auto "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>" 8、查看当前系统上root用户的所有信息; # grep "^root\>" /etc/passwd 9、添加用户bash和testbash、basher,而后找出当前系统上其用户名和默认shell相同的用户; # grep --color=auto "^\([[:alnum:]]\{1,\}\)\>.*\1$" /etc/passwd 10、找出netstat -tan命令执行的结果中以“LISTEN”或“ESTABLISHED”结尾的行; # netstat -tlan | egrep --color "LISTEN|ESTABLISHED[[:space:]]*$" 11、取出当前系统上所有用户的shell,要求:每种shell只显示一次,且按升序显示; # cut -d: -f7 /etc/passwd | sort -u