【正则表达式】
它是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。对于系统管理员来讲,正则表达式贯穿在我们的日常运维工作中,无论是查找某个文档,抑或查询某个日志文件分析其内容,都会用到正则表达式。
正则表达式元字符由以下字符组成: ^ $ . [ ] { } - ? * + ( ) | \ 正在表达式 描述 ^ 匹配行的开始 $ 匹配行尾的文本 . 匹配除换行符以外的任意字符 [] 匹配包含在[字符]之中的任意一个字符 [^] 匹配除了[^字符]之外的任意一个字符 [-] 匹配[]指定范围内的任意一个字符 {n} 匹配之前的项n次 {n,} 之前的项至少匹配n次 {n,m} 指定之前的项需要匹配的最小和最大次数 ? 匹配之前的项零次或一次 * 匹配之前的项零次或更多次 + 匹配之前的项一次或更多次 () 创建一个用于匹配的子串 | 匹配|两边的任意一项 \ 将上面特殊字符进行转义 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 \W 匹配任意不是字母,数字,下划线,汉字的字符 \S 匹配任意不是空白符的字符 \D 匹配任意非数字的字符 \B 匹配不是单词开头或结束的位置 示例: ^zhiyou 匹配以zhiyou开始的行 $zhiyou 匹配以zhiyou结尾的行 a.c 匹配abc、aac...但不匹配abbc ab[cd] 匹配abc或abd 1[^01] 匹配12、13,但不匹配10、11 [1-5] 匹配1-5之间的任意一个数字 [0-9]{2} 匹配任意一个两位数 [0-9]{2,} 匹配任意一个两位或更多位数字 [0-9]{2,5} 匹配从两位数到五位数之间的任意一个数字 zhiy?ou 匹配zhiyou 或 zhiou zhiy*ou 匹配zhiou、zhiyou、zhiyyou zhiy+ou 匹配zhiyou 、zhiyyou、zhiyyyyou ma(in)? 匹配 ma或main 1(2|3) 匹配12或13 a\+b 匹配a+b [实例:] 列出/etc/passwd中带有zy的行 grep 'z.*y' /etc/passwd 利用 Linux 系统自带的字典查找一个五个字母的单词,第三个字母为 j,最后一个字母为 r ,/usr/share/dict 目录下存放字典文件: grep '^..j.r$' /usr/share/dict/linux.words 搜索出a.txt中带有数字的行: grep [0-9] a.txt 验证固定电话,打印符合条件的电话,固定电话格式基本都是带有 0 的区号+连接符“-”+电话号码,另外还有可能有分机号,区号有 3 位、4 位,电话号码有 7 位和 8 位的: grep -E "^0[0-9]{2,3}-[0-9]{7,8}(-[0-9]{3,4})?$" telphone.txt
【管道命令】
管道是一种通信机制,通常用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式就是将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)。
管道又分为匿名管道和具名管道。我们在使用一些过滤程序时经常会用到的就是匿名管道,在命令行中由|分隔符表示。具名管道简单的说就是有名字的管道,通常只会在源程序中用到具名管道。 command1 | command2 | command3 把command1的正确结果作为 command2 的输入源,把command2的正确结果作为command3的输入源 显示出command3的正确结果 [实例:] 通过管道将前一个命令(ls)的输出作为下一个命令(less)的输入: ls -al /etc | less
相关命令
2.1 cut 打印某一行中的某个字段
语法:cut -d ‘分割字符’ -f fields
cut -c 字符范围
-d : 后面接分隔符,与-f一起使用; -f : 依据-d的分隔符将一段信息切割成为数段,用-f取出第几段的意思; -c : 以字符(characters)的单位取出固定字符区间; [实例:] 打印出/etc/passwd中用户名和用户家目录 cut /etc/passwd -d ':' -f 1,6 打印出文件权限,文件所属用户,文件名 ls -l |cut -d ' ' -f 1,3,12 打印/etc/passwd文件中每一行的前N个字符: # 前五个(包含第五个) $ cut /etc/passwd -c -5 # 前五个之后的(包含第五个) $ cut /etc/passwd -c 5- # 第五个 $ cut /etc/passwd -c 5 # 2到5之间的(包含第五个) $ cut /etc/passwd -c 2-5
2.2 grep分析一行数据,如果有匹配的,就显示出来
grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
语法:grep [-acinv] [–color=auto] ‘查找字符串’ filename
-a : 将binary文件以text文件的方式查找数据; -c : 计算找到’查找字符串‘的次数; -i : 忽略大小写的不同; -n : 带行号; -v : 反向选择,显示没有‘查找字符串’的行; --color=auto : 可以将找到查找的关键字部分加上颜色显示 -r 参数表示递归搜索子目录中的文件 -A:后跟一个数字(有无空格都可以),例如–A2则表示打印符合要求的行以及下面两行 -B:后跟一个数字,例如–B2则表示打印符合要求的行以及上面两行 -C:后跟一个数字,例如–C2则表示打印符合要求的行以及上下各两行 [实例:] 将/etc/passwd,有出现 root 的行取出来: grep root /etc/passwd 将/etc/passwd,有出现 root 的行取出来,同时显示这些行在/etc/passwd的行号: grep -n root /etc/passwd 将/etc/passwd,将没有出现 root 和nologin的行取出来: grep -v root /etc/passwd | grep -v nologin 搜索/home/smile目录下所有包含"zhiyou"的所有文本文件,并显示出现在文本中的行号: grep -rn "zhiyou" /home/smile 【参见正则表达式】 [另:egrep工具,是grep的扩展版本,以用egrep完成grep不能完成的工作,当然了grep能完成的egrep完全可以完成。]
2.3 sed工具
grep工具的功能其实还不够强大,其实说白了,grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。以前用vim的时候,可以查找也可以替换,但是只局限于在文本内部来操作,而不能输出到屏幕上。sed工具以及下面要讲的awk工具就能实现把替换的文本输出到屏幕上的功能了,而且还有其他更丰富的功能。sed和awk都是流式编辑器,是针对文档的行来操作的。
语法:
sed [options] ‘command’ file(s)
sed [options] -f scriptfile file(s)
选项: -e:以选项中的指定的script来处理输入的文本文件; -f:以选项中指定的script文件来处理输入的文本文件; -h:显示帮助; -n:仅显示script处理后的结果; -V:显示版本信息。 [命令:] a\ 在当前行下面插入文本。 i\ 在当前行上面插入文本。 c\ 把选定的行改为新的文本。 d 删除,删除选择的行。 D 删除模板块的第一行。 s 替换指定字符 p 打印模板块的行。 q 退出sed = 打印当前行号码 ..... [实例:] 1.打印a.txt中第二行内容: sed -n '2'p a.txt 2.打印整个a.txt文档: sed -n '1,$'p a.txt 3.打印包含123的行: sed -n '/123/'p a.txt 4.-e实现多个任务。打印包含a或者123的行 sed -e '/a/'p -e '/123/'p -n a.txt 5.删除第一行: sed '1'd a.txt 删除前三行: sed '1,3'd a.txt 【替换标记】 g 表示行内全面替换。 p 表示打印行。 w 表示把行写入一个文件。 x 表示互换模板块中的文本和缓冲区中的文本。 y 表示把一个字符翻译为另外的字符(但是不用于正则表达式) \1 子串匹配标记 & 已匹配字符串标记 [实例:] 1.替换'32'为'ab' sed 's/32/ab/g' a.txt (/可以换成#、@都可) 2.删除文档中所有数字或字母 sed 's/[0-9]//g' a.txt (删除所有数字) 3.直接修改文件内容 sed -i 's/32/ab/g' a.txt 【另:awk工具。awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的。】
2.5 sort 排序
语法:sort [-t分隔符] [-kn1,n2] [-nru]这里的n1 < n2
-t分隔符:作用跟cut的-d一个意思
-n:使用纯数字排序
-r:反向排序
-u:去重复
-kn1,n2:由n1区间排序到n2区间,可以只写-kn1,即对n1字段排序
[实例:] 对passwd中的前五行排序 head -n5 /etc/passwd |sort 对passwd中的前五行的第三个字段排序 head -n5 /etc/passwd |sort -t: -k3n
2.6 wc命令
wc 命令是一个统计的工具,主要用来显示文件所包含的行、字和字节数。
wc 命令是 word count 的缩写。
语法:wc [-lwm] 文件
-l : 统计行数
-w : 统计字数(英文单字,由空白、跳格或换行字符分隔的字符串)
-m : 统计字符数,这个标志不能与 -c 标志一起使用
-c : 统计字节数
[实例:] 统计a.txt文件行数: wc -l a.txt 统计文件的字符数,只打印数字,不打印文件名: cat a.txt | wc -m 统计/bin 目录下的命令个数,可以使用如下命令: ls /bin | wc -l
2.7 uniq 去重复的行
常用选项-c:统计重复的行数,并把行数写在前面
[实例:] 查看a.txt行数出现次数 cat a.txt| uniq -c (在进行uniq之前,需要先用sort排序然后才能uniq)
2.8 tee
tee:后跟文件名,类似与重定向”>”,但是比重定向多了一个功能,在把文件写入后面所跟的文件中的同时,还显示在屏幕上。
2.9
tr:替换字符,常用来处理文档中出现的特殊符号,如DOS文档中出现的^M符号。常用的选项有两个:
-d:删除某个字符,-d后面跟要删除的字符
-s:把重复的字符去掉
最常用的就是把小写变大写:tr ‘[a-z]’ ‘[A-Z]’
2.10
split:切割文档,常用选项:
-b:依据大小来分割文档,单位为byte
-l:依据行数来分割文档
[实例:] split -b 500 /etc/passwd passwd 后面的passwd为分割后文件名的前缀,分割后的文件名为passwdaa, passwdab, passwdac … wc -l /etc/passwd*
2.11
:分号。平时我们都是在一行中敲一个命令,然后回车就运行了,那么想在一行中运行两个或两个以上的命令如何呢?则需要在命令之间加一个”;”了。
2.12
&:如果想把一条命令放到后台执行的话,则需要加上这个符号。通常用于命令运行时间非常长的情况。
2.13
&&与||
在上面刚刚提到了分号,用于多条命令间的分隔符。另外还有两个可以用于多条命令中间的特殊符号,那就是 “&&”和”||”。把这几种情况全列出:
1) command1 ; command2
2) command1 && command2
3) command1 || command2
使用”;”时,不管command1是否执行成功都会执行command2;使用”&&”时,只有command1执行成功后,command2才会执行,否则command2不执行;使用”||”时,command1执行成功后command2不执行,否则去执行command2,总之command1和command2总有一条命令会执行。
【sed相关练习题:】
1.把/etc/passwd复制到/root/test.txt,用sed打印所有行;
2.打印test.txt的3到10行;
3.打印test.txt中包含’root’的行;
4.删除test.txt的15行以及以后所有行;
5.删除test.txt中包含’bash’的行;
6.替换test.txt中’root’为’toor’;
7.替换test.txt中’/sbin/nologin’为’/bin/login’
8.删除test.txt中5到10行中所有的数字;
9.删除test.txt中所有特殊字符(除了数字以及大小写字母);
10.把test.txt中第一个单词和最后一个单词调换位置;
11.把test.txt中出现的第一个数字和最后一个单词替换位置;
12.把test.txt中第一个数字移动到行末尾;
13.在test.txt 20行到末行最前面加’aaa:’;