鸟哥的Linux私房菜
基础学习篇第四版
1. sed工具
sed本身也是一个管道命令,可以分析标准输入。而且sek还可以将数据进行替换、删除、新增、选取等
sed [-nefr] [操作]
选项与参数
-n:使用安静模式(silent)模式,在一般sed的用法中,所有来自stdin的数据一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被列出来
-e:直接在命令行模式上进行sed的操作编辑
-f:直接将sed的操作卸载一个文件内,-f filename则可以执行filename内的sed操作
-i:直接修改读取的文件内容,而不是由屏幕输出
操作说明:[n1 [,n2]] function
n1,n2:非必须存在,一般代表【选择进行操作的行数】
function由以下操作:
- a:新增 ,a的后面接字符,而这些字符会在新的一行出现(目前的下一行);
- c:替换 ,c的后面可以接字符,这些字符可以替换n1,n2之间的行
- d:删除 ,因为是删除,所以后面往往不接任何东西
- i:插入 ,i的后面可以接字符,而这些字符会在新的一行出现(目前的上一行)
- p:打印 ,亦即将某个选择的数据打印出来,通常p会与参数sed -n 一起运行;
- s:替换,可以直接进行替换的工作,通常这个s的操作可以搭配正则表达式
1.1 示例:以行为单位的新增/删除功能
删除第2-5行
[root@master app]# nl /etc/passwd 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 sync:x:5:0:sync:/sbin:/bin/sync 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 halt:x:7:0:halt:/sbin:/sbin/halt 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 operator:x:11:0:operator:/root:/sbin/nologin 11 games:x:12:100:games:/usr/games:/sbin/nologin 12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13 nobody:x:99:99:Nobody:/:/sbin/nologin 14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin 15 dbus:x:81:81:System message bus:/:/sbin/nologin 16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin 17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin 19 dhcpd:x:177:177:DHCP server:/:/sbin/nologin 20 ntp:x:38:38::/etc/ntp:/sbin/nologin [root@master app]# [root@master app]# nl /etc/passwd |sed '2,5d' 1 root:x:0:0:root:/root:/bin/bash 6 sync:x:5:0:sync:/sbin:/bin/sync 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 halt:x:7:0:halt:/sbin:/sbin/halt 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 operator:x:11:0:operator:/root:/sbin/nologin 11 games:x:12:100:games:/usr/games:/sbin/nologin 12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13 nobody:x:99:99:Nobody:/:/sbin/nologin 14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin 15 dbus:x:81:81:System message bus:/:/sbin/nologin 16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin 17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin 19 dhcpd:x:177:177:DHCP server:/:/sbin/nologin 20 ntp:x:38:38::/etc/ntp:/sbin/nologin
2. awk:好用的数据处理工具
awk是一个非常棒的数据处理工具,awk倾向于一行当中分成数个字段来处理
awk '条件类型1{操作1} 条件类型2{操作2} ...' filename
awk主要是处理每一行的字段内的数据,而默认的字段的分隔符为“空格键”或“[Tab]键”
2.1 简易示例
想要取出账号与登陆者ip,且账号与ip之间以[Tab]隔开
[root@master app]# last -n 5 [root@master app]# last -n 5 root pts/0 192.168.23.1 Sun Dec 23 15:58 still logged in root pts/0 192.168.23.1 Sun Dec 23 07:20 - 15:40 (08:19) root pts/1 192.168.23.1 Sun Dec 23 05:39 - 09:07 (03:28) root pts/0 192.168.23.1 Fri Dec 21 23:47 - 07:07 (1+07:20) root pts/0 192.168.23.1 Thu Dec 20 17:28 - 18:16 (1+00:48) wtmp begins Tue Dec 11 13:53:15 2018 [root@master app]# [root@master app]# last -n 5|awk '{print $1 "\t" $3}' root 192.168.23.1 root 192.168.23.1 root 192.168.23.1 root 192.168.23.1 root 192.168.23.1 wtmp Tue
每一行的每个字段都是有变量名称,那就是$1、$2等变量名称。以上来讲root就是$1,ip地址就是$3,以此类推。还有个其他变量就是**$0**,代表 【一整列数据】的意思。以上例来讲第一行的$0就代表【root】那一列。因此可见上面5行整个awk的处理流程:
- 读入第1行,并将第1行的数据写入$0、$1、$2等变量当中
- 根据“条件类型”的限制,判断是否需要进行后面的“操作”
- 完成所有操作与条件类型
- 若还有后续的【行】的数据,则重复上面1-3的步骤,直到所有的数据都读完位置
因此可知awk是以行为依次处理的单位,以字段为最小的处理单位,name怎么知道数据有几行,几列呢?这就需要awk内置变量:
变量名称 | 代表意义 |
---|---|
NF | 每一行($0)拥有的字段总量 |
NR | 目前awk所处理的是第几行数据 |
FS | 目前的分隔字符,默认是空格键 |
以last -n 5的例子来说明,如果想要:
- 列出每一行的账号(就是$1)
- 列出目前处理的行数(就是awk内的NR变量)
- 并且说明改行有多少字段(就是awk内的NF变量)
[root@master app]# last -n 5|awk '{print $1 "\t lines: "NR" \t columns: " NF}' root lines: 1 columns: 10 root lines: 2 columns: 10 root lines: 3 columns: 10 root lines: 4 columns: 10 root lines: 5 columns: 10 lines: 6 columns: 0 wtmp lines: 7 columns: 7
2.2 逻辑运算字符
运算单元 | 代表意义 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
== | 等于 |
!= | 不等于 |
注意【==】符号
- 逻辑运算上面即所谓的大于、小于、等于等判断式上面,习惯上是以【==】来表示
- 如果直接赋予一个值,则直接使用【=】
2.2.1 示例
在/etc/passwd 当中以冒号":"来作为字段的分隔。假设要查看第三栏小于10以下的数据,并且仅列出账号与第三列
[root@master app]# cat /etc/passwd |awk '{FS=":"} $3<10 {print $1 "\t" $3}' root:x:0:0:root:/root:/bin/bash bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8
解析:
指定分隔符FS=":",判断第三栏小于10 $3<10, 输出第一列和第三列print $1 “\t” $3
问题:
第一行并没有被显示?因为我们读入第一行的时候变量$1等还是默认以空格风格,所以我们需要预先设置awk变量,利用BEGIN这个关键词:
[root@master app]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3 <10 {print $1 "\t" $3}' root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8
2.3 计算功能
假设有一个薪资报表文件名称为pay,内容为
Name 1st 2nd 3th SEK 23000 24000 25000 SDG 21000 20000 23000 SLE 43000 42000 41000
[root@master app]# cat pay |awk 'NR==1 {printf "%10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"} NR>=2{total =$2+$3+$4 printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$5,total}' me 1st 2nd 3th SEK 23000 24000 0 72000.00 SDG 21000 20000 0 64000.00 SLE 43000 42000 0 126000.00
3. 文件对比
3.1 diff命令
diff就是用在对比两个文件之间的差异,,并且以行为单位进行对比,一般是用在ASCII纯文本文件的对比上
diff [-bBi] from-file to-file
选项和参数
from-file:文件名,作为原始比对文件的文件名
to-file:文件名,作为目标对比文件的文件名
注意:以上两个文件可以用【-】来替换,代表【标准输入】
-b:忽略行中仅有多个空白的差异,即可理解为对比时多个空格视为1个空格处理
-B:忽略空白行的差异
-i:忽略大小写差异
3.2 cmp
相对于diff的功能呢,cmp就比较少用
cmp [-l] file1 file2
选项和参数
-l:将所有不同点的字节都列出来,因为cmp默认仅会输出第一个发现的不同点