Linux| 05文本操作 (cut sed awk sort)
正则表达式与文本搜索
元字符
- . 匹配除换行符外的任意单个字符;
- * 匹配任意一个跟在它前面的字符;
- [ ] 匹配方括号中的字符类中的任意一个;
- ^ 匹配开头;
- $ 匹配结尾;
- \ 转义后面的特殊字符;
[root@Linux100 ~]# grep password /root/anaconda-ks.cfg
# Root password
[root@Linux100 ~]# grep pass.... /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password
[root@Linux100 ~]# grep pass....$ /root/anaconda-ks.cfg
# Root password
[root@Linux100 ~]#
[root@Linux100 ~]# grep pass.* /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password
[root@Linux100 ~]# grep pass.*$ /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password
[root@Linux100 ~]# [Hh]ello hello Hello
bash: [Hh]ello: 未找到命令...
[root@Linux100 ~]#
[root@Linux100 ~]# grep ^# anaconda-ks.cfg
#version=DEVEL
# System authorization information
# Use CDROM installation media
# Use graphical install
# Run the Setup Agent on first boot
# Keyboard layouts
# System language
# Network information
# Root password
# System services
# System timezone
# X Window System configuration information
# System bootloader configuration
# Partition clearing information
# Disk partitioning information
[root@Linux100 ~]# grep "\." anaconda-ks.cfg
lang zh_CN.UTF-8
part pv.252 --fstype="lvmpv" --ondisk=sda --size=50175
volgroup centos --pesize=4096 pv.252
扩展元字符
- + 匹配前面的正则表达式至少出现一次;
- ? 匹配前面的正则表达式出现零次或一次;
- | 匹配它前面或后面的正则表达式;
文件的查找命令find
- find 路径 查找条件 [ 补充条件 ]
文本内容的过滤(查找)grep
正则表达式的匹配方式
字符串 Do one thing at a time, and do well.
匹配字符 an
[root@Linux100 etc]# cd /etc/
[root@Linux100 etc]# find passwd
passwd
[root@Linux100 etc]# ls passwd*
passwd passwd-
[root@Linux100 etc]# find /etc/ -name passwd
/etc/passwd
/etc/pam.d/passwd
[root@Linux100 etc]# find /etc/ -name pass*
find: 路径必须在表达式之前: passwd-
用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
[root@Linux100 etc]# find /etc/ -name passwd*
find: 路径必须在表达式之前: passwd-
用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
[root@Linux100 etc]#
[root@Linux100 etc]# man find
[root@Linux100 etc]#
[root@Linux100 etc]# find /etc -regex .*wd
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# find /etc -regex .*wd$
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# find /etc -regex .etc.*wd$
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# find /etc/ -type f -regex .*wd
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# cd
[root@Linux100 ~]#
[root@Linux100 ~]# echo 123 > file
[root@Linux100 ~]# stat file
文件:"file"
大小:4 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67155058 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 0/ root) Gid:( 0/ root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2022-10-01 14:15:47.328060474 +0800
最近更改:2022-10-01 14:15:47.328060474 +0800
最近改动:2022-10-01 14:15:47.328060474 +0800
创建时间:-
[root@Linux100 ~]# LANG=C stat file
File: 'file'
Size: 4 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 67155058 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:15:47.328060474 +0800
Modify: 2022-10-01 14:15:47.328060474 +0800
Change: 2022-10-01 14:15:47.328060474 +0800
Birth: -
[root@Linux100 ~]# touch file
[root@Linux100 ~]# LANG=C stat file
File: 'file'
Size: 4 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 67155058 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:16:48.992057117 +0800
Modify: 2022-10-01 14:16:48.992057117 +0800
Change: 2022-10-01 14:16:48.992057117 +0800
Birth: -
[root@Linux100 ~]#
[root@Linux100 ~]# chmod 755 file
[root@Linux100 ~]# LANG=C stat file
File: 'file'
Size: 4 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 67155058 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:16:48.992057117 +0800
Modify: 2022-10-01 14:16:48.992057117 +0800
Change: 2022-10-01 14:17:08.354056063 +0800
Birth: -
[root@Linux100 ~]# echo 123456 >> file
[root@Linux100 ~]# LANG=C stat file
File: 'file'
Size: 11 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 67155058 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:16:48.992057117 +0800
Modify: 2022-10-01 14:17:30.335054866 +0800
Change: 2022-10-01 14:17:30.335054866 +0800
Birth: -
[root@Linux100 ~]# mkdir tmp
[root@Linux100 ~]# cd tmp/
[root@Linux100 tmp]# touch {1..9}.txt
[root@Linux100 tmp]# ls
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
[root@Linux100 tmp]# find *.txt
1.txt
2.txt
3.txt
4.txt
5.txt
6.txt
7.txt
8.txt
9.txt
[root@Linux100 tmp]# find *txt -exec rm -v {} \;
已删除"1.txt"
已删除"2.txt"
已删除"3.txt"
已删除"4.txt"
已删除"5.txt"
已删除"6.txt"
已删除"7.txt"
已删除"8.txt"
已删除"9.txt"
[root@Linux100 tmp]#
[root@Linux100 tmp]#
[root@Linux100 tmp]#
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg | cut -d " " -f 1
auth
#
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg | cut -d " " -f 2
--enableshadow
Root
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg | cut -d " " -f 3
--passalgo=sha512
password
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | uniq -c
1 /bin/bash
4 /sbin/nologin
1 /bin/sync
1 /sbin/shutdown
1 /sbin/halt
34 /sbin/nologin
1 /bin/bash
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | sort uniq -c
sort: 打开失败: uniq: 没有那个文件或目录
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | sort | uniq -c
2 /bin/bash
1 /bin/sync
1 /sbin/halt
38 /sbin/nologin
1 /sbin/shutdown
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | sort | uniq -c | sort -r
38 /sbin/nologin
2 /bin/bash
1 /sbin/shutdown
1 /sbin/halt
1 /bin/sync
set 和awk
行编辑器介绍
- Vim和 sed、 AWK的区别;
- sed的基本用法演示;
- AWK的基本用法演示;
Vim和 sed、 AWK的区别:
- 交互式与非交互式;( vim编辑器交互式,set、awk是非交互式 )
- 文件操作模式与行操作模式;
sed 基本用法
sed 一般用于对文本内容做替换
sed '/user1/s/user1/u1' /etc/passwd
AWK基本用法
AWK一般用于对文本内容进行统计、按需要的格式进行输出
- cut 命令: cut -d : -f 1 /etc/passwd
- AWK命令: awk -F : '/wd$/{print$1}' /etc/passwd
sed的替换命令
① sed的模式空间
sed的基本工作方式是:
- 将文件以行为单位读取到内存(模式空间);
- 使用sed的每个脚本对该行进行操作;
- 处理完成后输出该行;
② 替换命令s
- sed 's/old/new/' filename
- sed -e 's/old/new/' -e 's/old/new/' filename ...
- sed -i 's/old/new/' 's/old/new/' filename ...
带正则表达式的替换命令s:
- sed 's/正则表达式/new/' filename
- sed -r 's/扩展正则表达式/new/' filename
[root@Linux100 tmp]# ls
[root@Linux100 tmp]# echo a a a > afile
[root@Linux100 tmp]#
[root@Linux100 tmp]# sed 's/a/aa/' afile
aa a a
[root@Linux100 tmp]# sed 's!/!abc!' afile
a a a
[root@Linux100 tmp]# sed -e 's/a/aa/' -e 's/aa/bb/' afile
bb a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile
bb a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile bfile cfile
bb a a
sed:无法读取 bfile:没有那个文件或目录
sed:无法读取 cfile:没有那个文件或目录
[root@Linux100 tmp]# cat afile
a a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile
bb a a
[root@Linux100 tmp]# sed -i 's/a/aa/;s/aa/bb/' afile
[root@Linux100 tmp]# cat afile
bb a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile > bfile
[root@Linux100 tmp]#
[root@Linux100 tmp]#
[root@Linux100 tmp]# head -5 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/...//'
t:x:0:0:root:/root:/bin/bash
:x:1:1:bin:/bin:/sbin/nologin
mon:x:2:2:daemon:/sbin:/sbin/nologin
:x:3:4:adm:/var/adm:/sbin/nologin
x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]#
# s*bin/表示s出现一次或者0次 bin
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/s*bin//'
root:x:0:0:root:/root://bash
:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/:/sbin/nologin
adm:x:3:4:adm:/var/adm://nologin
lp:x:4:7:lp:/var/spool/lpd://nologin
[root@Linux100 tmp]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@Linux100 tmp]#
[root@Linux100 tmp]# grep root /etc/passwd | sed 's/^root//'
:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
扩展元字符
[root@Linux100 tmp]# cat bfile
b
a
aa
aaa
ab
abb
abbb
# b出现一次或者0次
[root@Linux100 tmp]# sed 's/ab*/!/' bfile
b
!
!a
!aa
!
!
!
[root@Linux100 tmp]# cat bfile
b
a
aa
aaa
ab
abb
abbb
# ?表前面出现0次或1次
[root@Linux100 tmp]# sed -r 's/ab+/!/' bfile
b
a
aa
aaa
!
!
!
[root@Linux100 tmp]# cat bfile
b
a
aa
aaa
ab
abb
abbb
# 匹配a 或 b
[root@Linux100 tmp]# sed -r 's/a|b/!/' bfile
!
!
!a
!aa
!b
!bb
!bbb
# ()分组
[root@Linux100 tmp]# sed -r 's/(aa)|(bb)/!/' bfile
b
a
!
!a
ab
a!
a!b
#回调功能
[root@Linux100 tmp]# cat cfile
axyzb
[root@Linux100 tmp]# sed -r 's/(a.*b)/\1:\1/' cfile
axyzb:axyzb
sed的替换命令加强版
全局替换
s/old/new/g
- g为全局替换;
- 用于替换所有出现的次数;
- / 如果和正则匹配的内容冲突可以使用其他符合,如 s@old@new@g
标志位
s/old/new/标志位
- 数字,第n次出现才替换;
- g,每次出现都进行替换;
- p 打印模式空间的内容: sed -n 'script' filename 阻止默认输出;
- w file 将模式空间的内容写入到文件;
寻址
- 默认对每行进行操作,增加寻址后对匹配的行进行操作;
- /正则表达式/s/old/new/g
- 行内s/old/new/g,行号可以是具体的行,也可以是最后一行$符号;
- 可以使用两个寻址符号,也可以混合使用行号和正则地址;
分组
- 寻址可以匹配多条命令
- /regular/{s/old/new/;s/old/new/}
sed脚本文件
- 可以将选项保存为文件,使用-f 加载脚本文件;
- sed -f sedscript filename
[root@Linux100 tmp]# head -5 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]#
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/root/!!!!/'
!!!!:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/root/!!!!/g'
!!!!:x:0:0:!!!!:/!!!!:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/root/!!!!/2'
root:x:0:0:!!!!:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]#
[root@Linux100 tmp]#
[root@Linux100 tmp]#
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/root/!!!!/p'
!!!!:x:0:0:root:/root:/bin/bash
!!!!:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n 's/root/!!!!/p'
!!!!:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# vim /root/a
anaconda-ks.cfg anaconda-ks.cfg.bak a.sh a.txt
[root@Linux100 tmp]# vim /root/a.txt
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n 's/root/!!!!/p'
!!!!:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n 's/root/!!!!/w /root.a.txt'
[root@Linux100 tmp]# cat /root/a.txt
1.sh
2.sh
3.sh
4.sh
5.sh
anaconda-ks.cfg
a.sh
a.txt
b.txt
c.txt
d.txt
initial-setup-ks.cfg
mbr2.bin
mbr.bin
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n 's/root/!!!!/w /root/a.txt'
[root@Linux100 tmp]# cat /root/a.txt
!!!!:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# head -6 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed 's/adm/!/
> '
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
!:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed 's/adm/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
!:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed '1s/adm/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed '1,3s/adm/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed '1,$s/adm/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
!:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed 'root/s/bash/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed '2s/nologin/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed '/^bin/s/nologin/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]#
[root@Linux100 tmp]# head -6 /etc/passwd | sed '/^bin/,$s/nologin/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
daemon:x:2:2:daemon:/sbin:/sbin/!
adm:x:3:4:adm:/var/adm:/sbin/!
lp:x:4:7:lp:/var/spool/lpd:/sbin/!
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed '/^bin/,$s/nologin/!/g'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
daemon:x:2:2:daemon:/sbin:/sbin/!
adm:x:3:4:adm:/var/adm:/sbin/!
lp:x:4:7:lp:/var/spool/lpd:/sbin/!
sync:x:5:0:sync:/sbin:/bin/sync
sed其他指令
删除命令;
[寻址] d
- 删除模式空间内容,改变脚本的控制流,读取新的输入行;
[root@Linux100 tmp]# cat bfile
b
a
aa
aaa
ab
abb
abbb
[root@Linux100 tmp]# sed '/ab/d' bfile
b
a
aa
aaa
[root@Linux100 tmp]# sed '/ab/d;s/a/!/' bfile
b
!
!a
!aa
# 输出行号
[root@Linux100 tmp]# sed '/ab/d;=' bfile
1
b
2
a
3
aa
4
aaa
追加、插入和更改;
- 追加命令 a ;
- 插入命令 i ;
- 更改命令 c ;
[root@Linux100 tmp]# cat bfile
b
a
aa
aaa
ab
abb
abbb
[root@Linux100 tmp]# sed '/ab/i hello' bfile
b
a
aa
aaa
hello
ab
hello
abb
hello
abbb
[root@Linux100 tmp]# sed '/ab/a hello' bfile
b
a
aa
aaa
ab
hello
abb
hello
abbb
hello
[root@Linux100 tmp]# sed '/ab/c hello' bfile
b
a
aa
aaa
hello
hello
hello
[root@Linux100 tmp]# sed '/ab/r afile' bfile
b
a
aa
aaa
ab
bb a a
abb
bb a a
abbb
bb a a
[root@Linux100 tmp]# sed '/ab/r afile' bfile > rfile
打印;
- 打印命令p
下一行;
- 下一行命令 n
- 打印行号命令 =
读文件和写文件;
- 读文件命令 r
- 写文件命令 w
退出命令q
- 哪个效率会更高呢?
- sed 10q filename (它更高)
- sed -n 1,10p filename
[root@Linux100 tmp]# cat bfile
b
a
aa
aaa
ab
abb
abbb
[root@Linux100 tmp]# sed '/ab/p' bfile
b
a
aa
aaa
ab
ab
abb
abb
abbb
abbb
[root@Linux100 tmp]# sed -n '/ab/p' bfile
ab
abb
abbb
[root@Linux100 tmp]# seq 1 10
1
2
3
4
5
6
7
8
9
10
[root@Linux100 tmp]# seq 1 10000 > lines.txt
[root@Linux100 tmp]# wc -l lines.txt
10000 lines.txt
[root@Linux100 tmp]# sed -n '1,10p' lines.txt
1
2
3
4
5
6
7
8
9
10
[root@Linux100 tmp]# time sed -n '1,10p' lines.txt
1
2
3
4
5
6
7
8
9
10
real 0m0.002s
user 0m0.000s
sys 0m0.002s
[root@Linux100 tmp]# time sed -n '10p' lines.txt
10
real 0m0.002s
user 0m0.000s
sys 0m0.002s
sed多行模式空间
sed的多行模式
为什么要有多行模式?
- 配置文件一般为单行出现;
- 也有使用XML或JSON格式的配置文件,为多行出现;
多行模式处理命令N、 D、 P
- N 将下一行加入到模式空间;
- D 删除模式空间中的第一个字符到第一个换行符;
- P 打印模式空间中的第一个字符到第一个换行符;
[root@Linux100 tmp]# vim a.txt
[root@Linux100 tmp]# sed 'N' a.txt
hel
lo
[root@Linux100 tmp]# sed 'N;s/hello/!!!/' a.txt
hel
lo
[root@Linux100 tmp]# sed 'N;s/hel\nlo/!!!/' a.txt
!!!
[root@Linux100 tmp]# sed 'N;s/hel.lo/!!!/' a.txt
!!!
[root@Linux100 tmp]# cat > b.txt << EOF
> hell
> o bash hel
> lo bash
> EOF
[root@Linux100 tmp]# cat b.txt
hell
o bash hel
lo bash
[root@Linux100 tmp]# sed 'N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt
hello sed
hello sed
[root@Linux100 tmp]# sed 'N;N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt
hello sed
hel
lo bash
保持空间
- 保持空间也是多行的一种操作方式
- 将内容暂存在保持空间,便于做多行处理
保持空间命令
- h和H将模式空间内容存放到保持空间
- g和G将保持空间内容取出到模式空间
- x交换模式空间和保持空间内容
[root@Linux100 tmp]# head -6 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | cat -n
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
[root@Linux100 tmp]# head -6 /etc/passwd | cat -n | tac
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | set -n '1h;G;x;$p'
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed -n '1h;G;x;$p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed -n '1h;1!G;x;$p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed -n '1h;1!G;$!x;$p'
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]#
[root@Linux100 tmp]#
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed 'G;h'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed 'G;h$p'
sed:-e 表达式 #1,字符 4:命令后含有多余的字符
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed 'G;h;$p'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed -n 'G;h;$p'
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed -n '1!G;h;$p'
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 | sed '1!G;h;$!d'
6 sync:x:5:0:sync:/sbin:/bin/sync
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2 bin:x:1:1:bin:/bin:/sbin/nologin
1 root:x:0:0:root:/root:/bin/bash
AWK
AWK和 sed的区别
- awk更像是脚本语言;
- awk用于“比较规范”的文本处理,用于统计数量并输出指定字段;
- 使用sed将不规范的文本,处理为“比较规范”的文本;
AWK脚本的流程控制
- 输入数据前例程 BEGIN{ }
- 主输入循环 { }
- 所有文件读取完成例程 END { }
记录和字段
- 每行称作AWK的记录;
- 使用空格、制表符分隔开的单词称作字段;
- 可以自己指定分割的字段;
字段的引用
awk中使用$1 $2... $n 表示每一个字段;
- awk '{print $1, $2, $3}' filename
awk可以使用 -F 选项改变字段分隔符
- awk -F ',' '{print $1, $2, $3}' filename
- 分隔符可以使用正则表达式
[root@Linux100 ~]# awk -F "'" '/^menu/{ print $2 }' /boot/grub2/grub.cfg CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core) CentOS Linux (0-rescue-664dbe28ab4f4a9eb3041dd0dc965aed) 7 (Core) [root@Linux100 ~]# [root@Linux100 ~]# awk -F "'" '/^menu/{ print x++,$2 }' /boot/grub2/grub.cfg 0 CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core) 1 CentOS Linux (0-rescue-664dbe28ab4f4a9eb3041dd0dc965aed) 7 (Core)
AWK的表达式
① 赋值操作符
= 是最常用的赋值操作符
- var1 = "name"
- var2 = "hello" "world"
- var3 = $1 (表示分割开的第一个字段)
其他赋值操作符
- ++ -- += -= *= /= %= ^=
② 算数操作符
- + - * / % ^
③ 系统变量
- FS和OFS字段分隔符,OFS表示输出的字段分隔符,FS输入
- RS记录分隔符
- NR和FNR行数
- NF字段数量,最后一个字段内容可以用$NF 取出
④ 关系操作符
- < > <= >= == != ~ !~
⑤ 布尔操作符
- && || !
[root@Linux100 ~]# head -5 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@Linux100 ~]# [root@Linux100 ~]# head -5 /etc/passwd | awk -F ":" 'BEGIN{FS=":"} {print $1}' root bin daemon adm lp [root@Linux100 ~]# head -5 /etc/passwd | awk -F ":" 'BEGIN{FS=":"} {print $1,$2}' root x bin x daemon x adm x lp x [root@Linux100 ~]# head -5 /etc/passwd | awk -F ":" 'BEGIN{FS=":";OFS="-"} {print $1,$2}' root-x bin-x daemon-x adm-x lp-x [root@Linux100 ~]# [root@Linux100 ~]# head -5 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@Linux100 ~]# head -5 /etc/passwd | awk 'BEGIN{RS=":"} {print $0}' root x 0 0 root /root /bin/bash bin x 1 1 bin /bin /sbin/nologin daemon x 2 2 daemon /sbin /sbin/nologin adm x 3 4 adm /var/adm /sbin/nologin lp x 4 7 lp /var/spool/lpd /sbin/nologin [root@Linux100 ~]# head -5 /etc/passwd | awk '{print NR}' 1 2 3 4 5 [root@Linux100 ~]# head -5 /etc/passwd | awk '{print NR,$0}' 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 [root@Linux100 ~]# head -5 /etc/passwd | awk '{print NFR,$0}' root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@Linux100 ~]# [root@Linux100 ~]# [root@Linux100 ~]# [root@Linux100 ~]# awk '{print NFR,$0}' /etc/hosts /etc/hosts hosts hosts.allow hosts.deny [root@Linux100 ~]# awk '{print NFR,$0}' /etc/hosts /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.10.100 Linux100 192.168.10.101 Linux101 192.168.10.102 Linux102 192.168.10.103 Linux103 192.168.10.104 Linux104 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.10.100 Linux100 192.168.10.101 Linux101 192.168.10.102 Linux102 192.168.10.103 Linux103 192.168.10.104 Linux104 [root@Linux100 ~]# awk '{print NR,$0}' /etc/hosts /etc/hosts 1 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 2 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 3 192.168.10.100 Linux100 4 192.168.10.101 Linux101 5 192.168.10.102 Linux102 6 192.168.10.103 Linux103 7 192.168.10.104 Linux104 8 9 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 10 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 11 192.168.10.100 Linux100 12 192.168.10.101 Linux101 13 192.168.10.102 Linux102 14 192.168.10.103 Linux103 15 192.168.10.104 Linux104 16 [root@Linux100 ~]# [root@Linux100 ~]# head -5 /etc/passwd | awk 'BEGIN{FS=":"} {print NF}' 7 7 7 7 7 [root@Linux100 ~]# head -5 /etc/passwd | awk 'BEGIN{FS=":"} {print $NF}' /bin/bash /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin
AWK判断和循环
AWK的条件和循环
① 条件语句
- 条件语句使用if开头,根据表达式的结果来判断执行哪条语句
if (表达式)
awk语句1
[
awk语句2
]
- 如果有多个语句需要执行可以使用{ } 将多个语句括起来
② 循环
① while 循环
while(表达式)
awk语句1
② do循环
do{
awk语句1
}while(表达式)
③ for循环
for( 初始值; 循环判断条件; 累加 )
awk语句1
④ 影响控制的其他语句
- break
- continue
[root@Linux100 ~]# cat kpi.txt user1 70 72 74 76 74 72 user2 80 82 84 84 80 78 user3 60 61 62 63 64 65 user4 90 89 88 87 86 85 user5 45 60 63 62 61 50 [root@Linux100 ~]# awk '{if($2>=80) print $1}' kpi.txt user2 user4 [root@Linux100 ~]# awk '{if($2>=80) { print $1 ; print $2 } }' kpi.txt user2 80 user4 90 [root@Linux100 ~]# [root@Linux100 ~]# cat kpi.txt user1 70 72 74 76 74 72 user2 80 82 84 84 80 78 user3 60 61 62 63 64 65 user4 90 89 88 87 86 85 user5 45 60 63 62 61 50 [root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) print c}' 2 3 4 5 6 7 [root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) print $c}' 70 72 74 76 74 72 [root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum}' 438 [root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum/6}' 73 [root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum/(NF-1)}' 73 [root@Linux100 ~]# awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum/(NF-1)}' kpi.txt 73 154.333 216.833 304.333 361.167 [root@Linux100 ~]# cat kpi.txt user1 70 72 74 76 74 72 user2 80 82 84 84 80 78 user3 60 61 62 63 64 65 user4 90 89 88 87 86 85 user5 45 60 63 62 61 50 [root@Linux100 ~]# awk '{sum=0; for(c=2;c<=NF;c++) sum+=$c ; print sum/(NF-1)}' kpi.txt 73 81.3333 62.5 87.5 56.8333
awk数组
① 数组的定义
数组:一组有某种关联的数据(变量),通过下标依次访问;
- 数组名[下标] = 值
- 下标可以使用数字也可以使用字符串
② 数组的遍历
for (变量 in 数组名)
- 使用数组名[变量] 的方式依次对每个数组的元素进行操作
③ 删除数组
- delete 数组[下标]
④ 命令行参数数组
- ARGC
- ARGV
[root@Linux100 ~]# cat kpi.txt user1 70 72 74 76 74 72 user2 80 82 84 84 80 78 user3 60 61 62 63 64 65 user4 90 89 88 87 86 85 user5 45 60 63 62 61 50 [root@Linux100 ~]# awk '{ sum=0; for(column=2;column<=NF;column++) sum+=$column; average[$1]=sum/(NF-1)} END{ for( user in average) print user,average[user]}' kpi.txt user1 73 user2 81.3333 user3 62.5 user4 87.5 user5 56.8333 [root@Linux100 ~]# awk '{ sum=0; for(column=2;column<=NF;column++) sum+=$column; average[$1]=sum/(NF-1)} END{ for( user in average) sum2+=average[user] ; print sum2/NR }' kpi.txt 72.2333 [root@Linux100 ~]# awk '{ sum=0; for(column=2;column<=NF;column++) sum+=$column; average[$1]=sum/(NF-1)} END{ for( user in average) sum2+=average[user] ; print sum2}' kpi.txt 361.167 [root@Linux100 ~]# [root@Linux100 ~]# vim avg.awk BEGIN{ for(x=0;x<ARGC;x++) print ARGV[x] print ARGC } [root@Linux100 ~]# awk -f avg.awk 11 22 33 awk 11 22 33 4
awk数组功能的使用
[root@Linux100 ~]# vim result.awk { sum = 0 for( column = 2; column <= NF; column++ ) sum += $column average[$1] = sum / ( NF - 1) if( average[$1] >= 80 ) letter = "S" else if( average[$1] >= 70 ) letter = "A" else if( average[$1] >= 60 ) letter = "B" else letter = "C" print $1,average[$1],letter letter_all[letter]++ } END { for( user in average ) sum_all += average[user] avg_all = sum_all / NR print "average all:",avg_all for( user in average ) if( average[user] > avg_all ) above++ else below++ print "above",above print "below",below print "S",letter_all["S"] print "A",letter_all["A"] print "B",letter_all["B"] print "C",letter_all["C"] } [root@Linux100 ~]# awk -f result.awk kpi.txt user1 73 A user2 81.3333 S user3 62.5 B user4 87.5 S user5 56.8333 C average all: 72.2333 above 3 below 2 S 2 A 1 B 1 C 1
AWK的函数
① 算数函数
- sin() cos()
- int()
- rand() srand()
② 字符串函数
- gsub(r,s,t)
- index(s,t)
- length(s)
- match(s, r)
- split(s, q, seq)
- sub(r, s, t)
- substr(s, p, n)
③ 自定义函数
function 函数名(参数) {
awk语句
return awk变量
}
[root@Linux100 ~]# awk 'BEGIN{pi=3.14 ;print int(pi)}' 3 [root@Linux100 ~]# awk 'BEGIN{pi=3.14 rand()}' [root@Linux100 ~]# awk 'BEGIN{print rand()}' 0.237788 [root@Linux100 ~]# awk 'BEGIN{print rand()}' 0.237788 [root@Linux100 ~]# awk 'BEGIN{print rand()}' 0.237788 [root@Linux100 ~]# awk 'BEGIN{srand(); print rand()}' 0.823533 [root@Linux100 ~]# awk 'BEGIN{srand(); print rand()}' 0.679848 [root@Linux100 ~]# awk 'BEGIN{srand(); print rand()}' 0.105157 [root@Linux100 ~]# [root@Linux100 ~]# [root@Linux100 ~]# [root@Linux100 ~]# awk 'function a(){ return 0} BEGIN{ print a() }' 0 [root@Linux100 ~]# awk 'function double(str) {return str str } BEGIN{ print double("hello awk") }' hello awkhello awk
2. shell工具
cut
cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
-f (列号,提取第几列) -d(分隔符,按照指定分隔符分割列) -c (指定具体字符,如5--9个字符)
[root@kris datas]# ifconfig | grep Bcast
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
[root@kris datas]# ifconfig | grep Bcast | cut -c 11-14
inet
[root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2
192.168.1.100 Bcast
[root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 1
192.168.1.100
[root@kris datas]# ifconfig | grep Bcast > temp.log ##### > 是把原来的内容覆盖、>>是在原内容基础上追加;
[root@kris datas]# cat temp.log
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
[root@kris datas]# cut -d : -f 2 temp.log
192.168.1.100 Bcast
[root@kris datas]# cat temp.log | cut -d : -f 2 #####与上边是的等效的,只是temp.log所放的位置不一样
192.168.1.100 Bcast
[root@kris datas]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 3
Bcast
sed
sed按行处理;
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
-e(直接在指令列模式上进行sed的动作编辑;两个修改指令的方式) -i (在文件中直接编辑修改文件)
a(新增,a的后面可以接字串,在下一行出现 '2axxxx' ) d (删除)
s(查找并替换 ‘s/Link/xxxx/’ )
ifconfig | sed '1d' 删除第一行
ifconfig | sed '1,5d' 删除掉前5行
ifconfig | sed '1akris' 在第一行后面(第二行)追加kris
ifconfig | sed 's/Link/XXX/' 查找并替换;注意是区分大小写的,最后的/符号不要忘记了;
ifconfig | sed 's/Link/XXX/' temp.log #并不会改变文件内容
ifconfig | sed -i 's/Link/XXX/' temp.log 加上-i就可以在文件中修改成功了;前提是文件中的内容必须是ifconfig输出内容;
ifconfig | sed '/^ *R/aXXX' 前边有若干个空格,以R开头的
[root@kris datas]# ifconfig | sed -e '/^ *R/aXXX' -e'/^ *T/d'
以R开头的追加XXX,把以T开头的删掉;这是两个式子就不能通过一个式子搞定了,需加-e改变修改方式,只有一个时可以省略;
awk
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
按行处理,可以对行内的数据进行更细微的操作;
awk [选项参数] ‘pattern1{action1} pattern2{action2}...’ filename
pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
选项参数:-F(指定输入文件折分隔符)、-v(赋值一个用户定义变量)
cp /etc/passwd ./
[root@kris datas]# cat passwd | awk '/^a/{print}' 把以a开头的打印出来 [root@kris datas]# cat passwd | awk '/^a/{print}' adm:x:3:4:adm:/var/adm:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin [root@kris datas]# cat passwd | awk -F : '/^a/{print $1}' //-F指定输入文件折分隔符 adm avahi-autoipd abrt apache [root@kris datas]# cat passwd | awk -F: '/^a/{print $1} /^adm/{print}' 如果匹配到了以a开头就把print $1打印出来; 如果又匹配到了adm就把print整行打印出;
adm
adm:x:3:4:adm:/var/adm:/sbin/nologin
avahi-autoipd
abrt
apache
alex
#如果不写模板它就把所有行都打印出
[root@kris datas]# cat passwd | awk -F : '{print $1}'
......
[root@kris datas]# cat passwd | awk -F: 'BEGIN{print "begin"} {print$1} END{print "end"}'
#begin在数据输入之前先执行BEGIN这个块里边的;END是所有数据处理完了再执行这个块里边的东西;
begin
...
end
[kris@hadoop datas]$ cat passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:sh.....
[root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3} END{print "Sum="sum}' #把第3列的数值加到sum上,对文件的第3列做累加;
Sum=0
Sum=3222
[root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}' ###上面求和的过程
[root@kris datas]# which awk
/bin/awk
[root@kris datas]# ll /bin/awk
lrwxrwxrwx. 1 root root 4 9月 3 2013 /bin/awk -> gawk
[root@kris datas]# cat passwd | awk -F: -v sum=0 'BEGIN{print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}' #-v就是引入一个变量
awk的内置变量
[root@kris datas]# cat temp | awk 'BEGIN{sum=0}{sum+=1}/^$/{print sum}' #打印出文件的所有空行的行号,下面这种方法更简单;
[root@kris datas]# cat temp | awk '/^$/{print NR}' #NR就起到sum的作用; 也可这样写: awk '/^$/{print NR}' temp
2
3
5
7
8
10
11
12
[root@kris datas]# awk '/^$/{print FILENAME}' temp ##每列输出文件名
temp
temp
temp
[root@kris datas]# awk -F : '{print NF}' passwd #######NF是按:切割的列数,一共多少列;
7
7
7
...
[root@kris datas]# awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:"NF}' passwd
filename:passwd, linenumber:1,columns:7
filename:passwd, linenumber:2,columns:7
filename:passwd, linenumber:3,columns:7
[root@kris datas]# ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}'
192.168.1.100 Bcast
[root@kris datas]# ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'
192.168.1.100
一个目录下(包括子目录)一共有多少个java文件? 如何取得每一个文件的名称?
[kris@hadoop ~]$ sudo find / -name "*.java"
/root/anaconda3/pkgs/spyder-3.3.2-py37_0/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
/root/anaconda3/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
[kris@hadoop ~]$ sudo find / -name "*.java" | awk -F "/" '{print $NF}' 以/切割,NF这行一共有多少列,如一共8列,$NF表取第8列
example.java
example.java
[kris@hadoop ~]$ basename /opt/module/hive
hive
practice
使用Linux命令查询file1中空行所在的行号 [krs@hadoop101 datas]$ awk '/^$/{print NR}' file1.txt 5
1.有文件chengji.txt内容如下: 张三 40 李四 50 王五 60 使用Linux命令计算第二列的和并输出 [kris@hadoop datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}' ######### -F " " $2 分割的列不是从0开始数的,从1开始 150 2.用shell写一个脚本,对文本中无序的一列数字排序 [kris@hadoop datas]$ sort -n text.txt 1 2 3 4 5 6 7 8 9 10
[kris@hadoop datas]$ sort -n text.txt | awk '{sum+=$0; print $0} END{print "sum="sum}'
1
2
3
4
5
6
7
8
9
10
sum=55
3 用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”kris”的文件名称 [kris@hadoop datas]$ grep -r "kris" /home/ | cut -d : -f 1
sort
-n(依照数值的大小排序) 、 -r (以相反的顺序来排序) 、 -t (设置排序时所用的分隔字符) 、 -k(指定需要排序的列)
[root@kris datas]# cat passwd | grep ^a | sort -t : -k 3
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
[root@kris datas]# cat passwd | grep ^a | sort -t : -k 3 -n
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
[root@kris datas]# cat passwd | grep ^a | sort -t : -k 3 -nr
abrt:x:173:173::/etc/abrt:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kris datas]# sort -t : -nrk 3 sort.sh
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6