本节课程目标
1. grep工具
grep是行过滤工具;用于根据关键字进行行过滤
语法和选项
语法:
# grep [选项] '关键字' 文件名
常见选项:
OPTIONS:-i: 不区分大小写-v: 查找不包含指定内容的行,反向选择-w: 按单词搜索-o: 打印匹配关键字-c: 统计匹配到的行数-n: 显示行号-r: 逐层遍历目录查找-m: 匹配到多少条之后停止-A: 显示匹配行及后面多少行-B: 显示匹配行及前面多少行-C: 显示匹配-l:只列出匹配的文件名-L:列出不匹配的文件名-e: 使用正则匹配-E:使用扩展正则匹配^key:以关键字开头key$:以关键字结尾^$:匹配空行--color=auto :可以将找到的关键词部分加上颜色的显示
颜色显示(别名设置):
临时设置:# alias grep='grep --color=auto' //只针对当前终端和当前用户生效永久设置:1)全局(针对所有用户生效)vim /etc/bashrcalias grep='grep --color=auto'source /etc/bashrc2)局部(针对具体的某个用户)vim ~/.bashrcalias grep='grep --color=auto'source ~/.bashrc
举例说明:
说明:不要直接使用/etc/passwd文件,将其拷贝到/tmp下做实验!
grep -e 'mail|ftp' 多条件过滤 过滤包含maiil或者ftp的行grep -i root passwd 忽略大小写匹配包含root的行grep -w ftp passwd 精确匹配ftp单词grep -w hello passwd 精确匹配hello单词;自己添加包含hello的行到文件grep -wo ftp passwd 打印匹配到的关键字ftpgrep -n root passwd 打印匹配到root关键字的行好grep -ni root passwd 忽略大小写匹配统计包含关键字root的行grep -nic root passwd 忽略大小写匹配统计包含关键字root的行数grep -i ^root passwd 忽略大小写匹配以root开头的行grep bash$ passwd 匹配以bash结尾的行grep -n ^$ passwd 匹配空行并打印行号grep ^# /etc/vsftpd/vsftpd.conf 匹配以#号开头的行grep -v ^# /etc/vsftpd/vsftpd.conf 匹配不以#号开头的行grep -A 5 mail passwd 匹配包含mail关键字及其后5行grep -B 5 mail passwd 匹配包含mail关键字及其前5行grep -C 5 mail passwd 匹配包含mail关键字及其前后5行
文件从后往前快速查找
从文件尾部查找用特定的 tac 命令,然后用管道命令后接 grep 匹配指定命令,具体示例如下:tac sout.log | grep 'api input'
匹配指定条数后停止
文件从后向前匹配的基础上,匹配指定的条数记录后停止可以如下命令:tac sout.log | grep 'api input' -m 5
通过 grep 的命令参数 -m 后面指定匹配的条数值。
也可以在此基础上,若要显示匹配上下文,还需要加如下几个命令:
- -C 后面跟上下文的行数,C 理解为 Context。
- -A 后面跟匹配行数之后行数值,A 表示 After。
- -B 后面跟匹配行数之前行数值,B 表示 Before。
tac sout.log | grep 'api input' -m 5 -A 2
2. cut工具
cut是列截取工具,用于列的截取
语法和选项
语法:
# cut 选项 文件名
常见选项:
-c: 以字符为单位进行分割,截取-d: 自定义分隔符,默认为制表符\t-f: 与-d一起使用,指定截取哪个区域--output-delimiter= :指定输出分界符
举例说明:
cut -d: -f1 1.txt 以:冒号分割,截取第1列内容cut -d: -f1,6,7 1.txt 以:冒号分割,截取第1,6,7列内容cut -c4 1.txt 截取文件中每行第4个字符cut -c1-4 1.txt 截取文件中每行的1-4个字符cut -c4-10 1.txt 截取文件中每行的4-10个字符cut -c5- 1.txt 从第5个字符开始截取后面所有字符
课堂练习:
用小工具列出你当系统的运行级别。5/3
- 如何查看系统运行级别
- 命令
runlevel - 文件
/etc/inittab
- 命令
- 如何过滤运行级别
runlevel |cut -c3runlevel | cut -d ' ' -f2grep -v '^#' /etc/inittab | cut -d: -f2grep '^id' /etc/inittab |cut -d: -f2grep "initdefault:$" /etc/inittab | cut -c4grep -v ^# /etc/inittab |cut -c4grep 'id:' /etc/inittab |cut -d: -f2cut -d':' -f2 /etc/inittab |grep -v ^#cut -c4 /etc/inittab |tail -1cut -d: -f2 /etc/inittab |tail -1
3. sort工具
sort工具用于排序;它将文件的每一行作为一个单位,从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
语法和选项
-u :去除重复行-r :降序排列,默认是升序-o : 将排序结果输出到文件中,类似重定向符号>-n :以数字排序,默认是按字符排序-t :分隔符-k :第N列-b :忽略前导空格。-R :随机排序,每次运行的结果均不同
举例说明
sort -n -t: -k3 1.txt 按照用户的uid进行升序排列sort -nr -t: -k3 1.txt 按照用户的uid进行降序排列sort -n 2.txt 按照数字排序sort -nu 2.txt 按照数字排序并且去重sort -nr 2.txtsort -nru 2.txtsort -nru 2.txtsort -n 2.txt -o 3.txt 按照数字排序并将结果重定向到文件sort -R 2.txtsort -u 2.txtsort -t' ' -kn,m -u 以空格为分隔符,按照第n到m列的内容进行排序,并去重要对某一列内容进行排序去重,n=m即可
4.uniq工具
uniq用于去除连续的重复行
常见选项:-c, --count 统计重复行次数prefix lines by the number of occurrences-d, --repeated 只显示重复行only print duplicate lines, one for each group-D print all duplicate lines--all-repeated[=METHOD] like -D, but allow separating groupswith an empty line;METHOD={none(default),prepend,separate}-f, --skip-fields=N 不要比较前 N 个域--group[=METHOD] show all items, separating groups with an empty line;METHOD={separate(default),prepend,append,both}-i, --ignore-case 比较时忽略大小写差异-s, --skip-chars=N 不要比较起始 N 个字符-u, --unique 只输出不重复(内容唯一)的行求差集,找不同-z, --zero-terminated 以 NUL 空字符而非换行符作为行尾分隔符-w, --check-chars=N 对每行第N 个字符以后的内容不作对照--help 显示此帮助信息并退出--version 显示版本信息并退出举例说明:uniq 2.txtuniq -d 2.txtuniq -dc 2.txt
5.tee工具
tee工具是从标准输入读取并写入到标准输出和文件,即:双向覆盖重定向(屏幕输出|文本输入)
选项:-a 双向追加重定向 ,内容追加到给定的文件而非覆盖-i, --ignore-interrupts 忽略中断信号-p 对写入非管道的行为排查错误--output-error[=模式] 设置写入出错时的行为。见下面“模式”部分--help 显示此帮助信息并退出--version 显示版本信息并退出echo hello worldecho hello world|tee file1cat file1echo 999|tee -a file1cat file1
6.diff工具
diff工具用于逐行比较文件的不同
注意:diff描述两个文件不同的方式是告诉我们怎样改变第一个文件之后与第二个文件匹配。
语法和选项
语法:
diff [选项] 文件列表用法:diff [选项]... 文件列表逐行比较<各文件>。长选项的必需参数也是相应短选项的必需参数。--normal 以正常的 diff 方式输出 (默认)-q, --brief 只有在文件不同时报告-s, --report-identical-files 当两个一样时仍然显示结果-c, -C NUM, --context[=NUM] 同时输出 NUM 行(默认为 3 行)的复制上下文内容-u, -U 数量, --unified[=数量] 输出 <数量>(默认为 3)行一致化上下文-e, --ed 以 ed script 方式输出-n, --rcs 以 RCS diff 格式输出-y, --side-by-side 以两栏的格式输出-W, --width=数量 每行显示最多 <数量>(默认 130)个字符--left-column 当有两行相同时只显示左边栏的一行--suppress-common-lines 当有两行相同时不显示-p, --show-c-function 显示每个变更位于哪个 C 函数中-F, --show-function-line=正则 显示匹配给定<正则>表达式的最近一行--label 标签 使用给定<标签>替代文件名和时间戳(可以重复)-t, --expand-tabs 将输出中的 tab 转换成空格-T, --initial-tab 每行先加上 tab 字符,使 tab 字符可以对齐--tabsize=数字 TAB 格的宽度,默认为 8 个打印列宽--suppress-blank-empty 在空的输出行之前去除空白或制表符-l, --paginate 将输出送至 “pr” 指令来分页-r, --recursive 连同所有子目录一起比较--no-dereference 不要跟随符号链接-N, --new-file 不存在的文件以空文件方式处理--unidirectional-new-file 若第一文件不存在,以空文件处理--ignore-file-name-case 忽略文件名大小写的区别--no-ignore-file-name-case 不忽略文件名大小写的区别-x, --exclude=模式 排除匹配 <模式> 的文件-X, --exclude-from=文件 排除所有匹配在<文件>中列出的模式的文件-S, --starting-file=文件 当比较目录時,由<文件>开始比较--from-file=文件1 将<文件1>和操作数中的所有文件/目录作比较;<文件1>可以是目录--to-file=文件2 将操作数中的所有文件/目录和<文件2>作比较;<文件2>可以是目录-i, --ignore-case 忽略文件内容大小写的区别-E, --ignore-tab-expansion 忽略由制表符宽度造成的差异-Z, --ignore-trailing-space 忽略每行末端的空格-b, --ignore-space-change 忽略由空格数不同造成的差异-w, --ignore-all-space 忽略所有空格-B, --ignore-blank-lines 忽略任何因空行而造成的差异-I, --ignore-matching-lines=正则 若某行完全匹配 <正则>,则忽略由该行造成的差异-a, --text 所有文件都以文本方式处理--strip-trailing-cr 去除输入内容每行末端的回车(CR)字符-D, --ifdef=名称 输出的内容以 ‘#ifdef <名称>’ 方式标明差异--GTYPE-group-format=GFMT 以 GFMT 格式处理 GTYPE 输入行组--line-format=LFMT 以 LFMT 格式处理每一行资料--LTYPE-line-format=LFMT 以 LFMT 格式处理 LTYPE 输入的行-d, --minimal 尽可能找出最小的差异集--horizon-lines=数量 保持<数量>行的一致前后缀--speed-large-files 假设文件十分大而且文件中含有许多微小的差异--color[=何时] 给输出上色;“何时”可以是“never”(从不)、“always”(总是)或“auto”(自动,默认)--palette=调色板 在 --color 选项启用时使用的颜色;<调色板>参数应当是一个冒号分隔的列表以提供 terminfo capabilities 信息
常用选项:
| 选项 | 含义 | 备注 |
|---|---|---|
| -b | 不检查空格 | |
| -B | 不检查空白行 | |
| -i | 不检查大小写 | |
| -w | 忽略所有的空格 | |
| —normal | 正常格式显示(默认) | |
| -c | 上下文格式显示 | |
| -u | 合并格式显示 |
举例说明:
- 比较两个普通文件异同,文件准备:
[root@MissHou ~]# cat file1aaaa111hello world222333bbb[root@MissHou ~]#[root@MissHou ~]# cat file2aaahello111222bbb333world[root@MissHou ~]# diff -u file1 file2 >diff.log[root@MissHou ~]# rm -f file2# 备份file1 -> file1.orig 找回file2 -> file1[root@MissHou ~]# patch -b file1 diff.log
1)正常显示
diff目的:file1如何改变才能和file2匹配[root@MissHou ~]# diff file1 file21c1,2 第一个文件的第1行需要改变(c=change)才能和第二个文件的第1到2行匹配< aaaa 小于号"<"表示左边文件(file1)文件内容--- ---表示分隔符> aaa 大于号">"表示右边文件(file2)文件内容> hello3d3 第一个文件的第3行删除(d=delete)后才能和第二个文件的第3行匹配< hello world5d4 第一个文件的第5行删除后才能和第二个文件的第4行匹配< 3336a6,7 第一个文件的第6行增加(a=add)内容后才能和第二个文件的第6到7行匹配> 333 需要增加的内容在第二个文件里是333和world> world
2)上下文格式显示
[root@MissHou ~]# diff -c file1 file2前两行主要列出需要比较的文件名和文件的时间戳;文件名前面的符号***表示file1,---表示file2*** file1 2019-04-16 16:26:05.748650262 +0800--- file2 2019-04-16 16:26:30.470646030 +0800*************** 我是分隔符*** 1,6 **** 以***开头表示file1文件,1,6表示1到6行! aaaa !表示该行需要修改才与第二个文件匹配111- hello world -表示需要删除该行才与第二个文件匹配222- 333 -表示需要删除该行才与第二个文件匹配bbb--- 1,7 ---- 以---开头表示file2文件,1,7表示1到7行! aaa 表示第一个文件需要修改才与第二个文件匹配! hello 表示第一个文件需要修改才与第二个文件匹配111222bbb+ 333 表示第一个文件需要加上该行才与第二个文件匹配+ world 表示第一个文件需要加上该行才与第二个文件匹配
3)合并格式显示
[root@MissHou ~]# diff -u file1 file2前两行主要列出需要比较的文件名和文件的时间戳;文件名前面的符号---表示file1,+++表示file2--- file1 2019-04-16 16:26:05.748650262 +0800+++ file2 2019-04-16 16:26:30.470646030 +0800@@ -1,6 +1,7 @@-aaaa+aaa+hello111-hello world222-333bbb+333+world
- 比较两个目录不同
默认情况下也会比较两个目录里相同文件的内容[root@MissHou tmp]# diff dir1 dir2diff dir1/file1 dir2/file10a1> helloOnly in dir1: file3Only in dir2: test1如果只需要比较两个目录里文件的不同,不需要进一步比较文件内容,需要加-q选项[root@MissHou tmp]# diff -q dir1 dir2Files dir1/file1 and dir2/file1 differOnly in dir1: file3Only in dir2: test1
其他小技巧:
有时候我们需要以一个文件为标准,去修改其他文件,并且修改的地方较多时,我们可以通过打补丁的方式完成。
1)先找出文件不同,然后输出到一个文件[root@MissHou ~]# diff -uN file1 file2 > file.patch-u:上下文模式-N:将不存在的文件当作空文件2)将不同内容打补丁到文件[root@MissHou ~]# patch file1 file.patchpatching file file13)测试验证[root@MissHou ~]# diff file1 file2[root@MissHou ~]#
7. paste工具
paste工具用于合并文件行
常用选项:-d:自定义间隔符,默认是tab-s:串行处理,非并行
8. tr工具
tr用于字符转换,替换和删除;主要用于删除文件中控制字符或进行字符转换
语法和选项
语法:
用法1:命令的执行结果交给tr处理,其中string1用于查询,string2用于转换处理commands|tr 'string1' 'string2'用法2:tr处理的内容来自文件,记住要使用"<"标准输入tr 'string1' 'string2' < filename用法3:匹配string1进行相应操作,如删除操作tr [options] 'string1' < filename
常用选项:
-c 用字符串1中字符集的补集替换此字符集,要求字符集为ASCII-d 删除字符串1中所有输入字符。-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串
常匹配字符串:
| 字符串 | 含义 | 备注 |
|---|---|---|
| a-z 或[:lower:] |
匹配所有小写字母 | 所有大小写和数字[a-zA-Z0-9] |
| A-Z 或[:upper:] |
匹配所有大写字母 | |
| 0-9 或[:digit:] |
匹配所有数字 | |
| [:alnum:] | 匹配所有字母和数字 | |
| [:alpha:] | 匹配所有字母 | |
| [:blank:] | 所有水平空白 | |
| [:punct:] | 匹配所有标点符号 | |
| [:space:] | 所有水平或垂直的空格 | |
| [:cntrl:] | 所有控制字符 | \f Ctrl-L 走行换页 \n Ctrl-J 换行 Ctrl-M 回车 \t Ctrl-I tab键 |
举例说明:
[root@MissHou shell01]# cat 3.txt 自己创建该文件用于测试ROOT:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltmail:x:8:12:mail:/var/spool/mail:/sbin/nologinuucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologinboss02:x:516:511::/home/boss02:/bin/bashvip:x:517:517::/home/vip:/bin/bashstu1:x:518:518::/home/stu1:/bin/bashmailnull:x:47:47::/var/spool/mqueue:/sbin/nologinsmmsp:x:51:51::/var/spool/mqueue:/sbin/nologinaaaaaaaaaaaaaaaaaaaabbbbbb111111122222222222233333333cccccccchello world 888666777999tr -d '[:/]' < 3.txt 删除文件中的:和/cat 3.txt |tr -d '[:/]' 删除文件中的:和/tr '[0-9]' '@' < 3.txt 将文件中的数字替换为@符号tr '[a-z]' '[A-Z]' < 3.txt 将文件中的小写字母替换成大写字母tr -s '[a-z]' < 3.txt 匹配小写字母并将重复的压缩为一个tr -s '[a-z0-9]' < 3.txt 匹配小写字母和数字并将重复的压缩为一个tr -d '[:digit:]' < 3.txt 删除文件中的数字tr -d '[:blank:]' < 3.txt 删除水平空白tr -d '[:space:]' < 3.txt 删除所有水平和垂直空白df | tr -s ' ' : | cut -d: -f1,3 把所有空格压缩成:,再按:分割取出第1,3列
小试牛刀
- 使用小工具分别截取当前主机IP;截取NETMASK;截取广播地址;截取MAC地址
ifconfig eth0|grep 'Bcast'|tr -d '[a-zA-Z ]'|cut -d: -f2,3,410.1.1.1:10.1.1.255:255.255.255.0ifconfig eth0|grep 'Bcast'|tr -d '[a-zA-Z ]'|cut -d: -f2,3,4|tr ':' '\n'10.1.1.110.1.1.255255.255.255.0ifconfig eth0|grep 'HWaddr'|cut -d: -f2-|cut -d' ' -f400:0C:29:25:AE:54ifconfig eth0|grep 'HW'|tr -s ' '|cut -d' ' -f500:0C:29:B4:9E:4Eifconfig eth1|grep Bcast|cut -d: -f2|cut -d' ' -f1ifconfig eth1|grep Bcast|cut -d: -f2|tr -d '[ a-zA-Z]'ifconfig eth1|grep Bcast|tr -d '[:a-zA-Z]'|tr ' ' '@'|tr -s '@'|tr '@' '\n'|grep -v ^$ifconfig eth0|grep 'Bcast'|tr -d [:alpha:]|tr '[ :]' '\n'|grep -v ^$ifconfig eth1|grep HWaddr|cut -d ' ' -f11ifconfig eth0|grep HWaddr|tr -s ' '|cut -d' ' -f5ifconfig eth1|grep HWaddr|tr -s ' '|cut -d' ' -f5ifconfig eth0|grep 'Bcast'|tr -d 'a-zA-Z:'|tr ' ' '\n'|grep -v '^$'
- 将系统中所有普通用户的用户名、密码和默认shell保存到一个文件中,要求用户名密码和默认shell之间用tab键分割
grep 'bash$' passwd |grep -v 'root'|cut -d: -f1,2,7|tr ':' '\t' |tee abc.txt
9. wc计数器
语法和选项
语法:
语法:用法:wc [选项]... [文件]...打印对每个给定文件的新行、单词和字节计数的结果;如果指定了超过一个文件,则还会打印一个总行数。此处的一个单词是指由空白字符分隔的长度大于零的字符序列。或:wc [选项]... --files0-from=F输出每个指定文件的行数、单词计数和字节数,如果指定了多于一个文件,继续给出所有相关数据的总计。如果没有指定文件,或者文件为"-",则从标准输入读取数据。
常用选项:
-c, --bytes 输出字节数统计-m, --chars 输出字符数统计-l, --lines 输出行数统计--files0-from=文件 从指定文件读取以空字符(NUL)终止的名称;如果该文件被指定为 - 则从标准输入读文件名-L, --max-line-length 显示最长行的长度-w, --words 显示单词计数--help 显示此帮助信息并退出--version 显示版本信息并退出
10. bc计算器
echo 2*3 | bc-h --help print this usage and exit-i --interactive force interactive mode-l --mathlib use the predefined math routines-q --quiet not print initial banner-s --standard non-standard bc constructs are errors-w --warn warn about non-standard bc constructs-v --version print version information and exit
11.随机字符
cat /dev/urandom | tr -dc a-zA-Z0-9#@ | head -c 13echo $RANDOMseq 首数 增量 尾数 生成连续数字 类似于python中的rangeseq 10 | sort - R 1-10生成乱序数字
12.反转字符串rev
二、bash的特性
1、命令和文件自动补全
Tab只能补全命令和文件 (RHEL6/Centos6)
2、常见的快捷键
^c 终止前台运行的程序^z 将前台运行的程序挂起到后台^d 退出 等价exit^l 清屏^a |home 光标移到命令行的最前端^e |end 光标移到命令行的后端^u 删除光标前所有字符^k 删除光标后所有字符^r 搜索历史命令
3、常用的通配符(重点)
*: 匹配0或多个任意字符?: 匹配任意单个字符[list]: 匹配[list]中的任意单个字符,或者一组单个字符 [a-z][!list]: 匹配除list中的任意单个字符{string1,string2,...}:匹配string1,string2或更多字符串rm -f file*cp *.conf /dir1touch file{1..5}
4、bash中的引号(重点)
- 双引号”” :会把引号的内容当成整体来看待,允许通过$符号引用其他变量值
- 单引号’’ :会把引号的内容当成整体来看待,禁止引用其他变量值,shell中特殊符号都被视为普通字符
- 反撇号`` :反撇号和$()一样,引号或括号里的命令会优先执行,如果存在嵌套,反撇号不能用
[root@MissHou dir1]# echo "$(hostname)"server[root@MissHou dir1]# echo '$(hostname)'$(hostname)[root@MissHou dir1]# echo "hello world"hello world[root@MissHou dir1]# echo 'hello world'hello world[root@MissHou dir1]# echo $(date +%F)2018-11-22[root@MissHou dir1]# echo `echo $(date +%F)`2018-11-22[root@MissHou dir1]# echo `date +%F`2018-11-22[root@MissHou dir1]# echo `echo `date +%F``date +%F[root@MissHou dir1]# echo $(echo `date +%F`)2018-11-22
