Linux学习05-sed、awk和文本对比

鸟哥的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由以下操作:

  1. a:新增 ,a的后面接字符,而这些字符会在新的一行出现(目前的下一行);
  2. c:替换 ,c的后面可以接字符,这些字符可以替换n1,n2之间的行
  3. d:删除 ,因为是删除,所以后面往往不接任何东西
  4. i:插入 ,i的后面可以接字符,而这些字符会在新的一行出现(目前的上一行)
  5. p:打印 ,亦即将某个选择的数据打印出来,通常p会与参数sed -n 一起运行;
  6. 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行,并将第1行的数据写入$0、$1、$2等变量当中
  2. 根据“条件类型”的限制,判断是否需要进行后面的“操作”
  3. 完成所有操作与条件类型
  4. 若还有后续的【行】的数据,则重复上面1-3的步骤,直到所有的数据都读完位置
    因此可知awk是以行为依次处理的单位,以字段为最小的处理单位,name怎么知道数据有几行,几列呢?这就需要awk内置变量:
变量名称代表意义
NF每一行($0)拥有的字段总量
NR目前awk所处理的是第几行数据
FS目前的分隔字符,默认是空格键

以last -n 5的例子来说明,如果想要:

  1. 列出每一行的账号(就是$1)
  2. 列出目前处理的行数(就是awk内的NR变量)
  3. 并且说明改行有多少字段(就是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默认仅会输出第一个发现的不同点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值