sed练习
所有以192.168.0.1开头的加上localhost
[root@web01 tmp]# cat /tmp/a1
192.168.0.1 test1
192.168.0.1 test2
方法一:
[root@web01 tmp]# sed 's/^\(192.168.0.1\)/\1 localhost/' /tmp/a1
192.168.0.1 localhost test1
192.168.0.1 localhost test2
方法二:
[root@web01 tmp]# sed 's/^192\.168\.0\.1/& localhost/' a1
192.168.0.1 localhost test1
192.168.0.1 localhost test2
打印奇数行或偶数行
[root@web01 tmp]# cat a
1
2
3
4
5
6
7
1~2表示从第一行开始打印,然后跳两行,再打印
[root@web01 tmp]# sed -n '1~2p' a
1
3
5
7
[root@web01 tmp]# sed -n '2~2p' a
2
4
6
n表示读取模式空间的下一行
[root@web01 tmp]# sed -n 'p;n' a
1
3
5
7
[root@web01 tmp]# sed -n 'n;p' a
2
4
6
对于包含test和west的行,在后面加上aaa bbb
[root@web01 tmp]# cat a2
1 test
2 test
3 west
4
5
6
使用 |
扩展正则表达式,或的意思
[root@web01 tmp]# sed -r 's/.*west.* | .*test.*/& aaa bbb/' a2
1 test aaa bbb
2 test aaa bbb
3 west
4
5
6
[root@web01 tmp]# sed -r 's/.*west.*|.*test.*/& aaa bbb/' a2
1 test aaa bbb
2 test aaa bbb
3 west aaa bbb
4
5
6
查找包含line1的行到包含line2的行之间的所有aa bbb变成AA BBB
[root@web01 tmp]# cat a3
line1
sfs
aa bbb
aa bbb line2
[root@web01 tmp]# sed '/line1/,/line2/s/aa bbb/AA BBB/g' a3
line1
sfs
AA BBB
AA BBB line2
找到某行打印它的下几行,找到test1,找到它的下三行
[root@web01 tmp]# cat a4
test1
1
2
3
test2
1
2
3
[root@web01 tmp]# sed '/test1/,+3p' a4 -n
test1
1
2
3
[root@web01 tmp]# sed '/test1/+3p' a4 -n
sed: -e expression #1, char 8: unknown command: `+'
在所有的每行后方添加一个空白行
取出文本中的第一行
[root@web01 tmp]# sed '1p' -n a
1
删除所有的空行然后在每个非空行上添加一个空行。
思路:先删除所有空行,然后把非空行匹配出来换成&\n
[root@web01 tmp]# cat a5
1
2
3
4
5
6
[root@web01 tmp]# sed '/^$/d' a5 | sed 's/..*/&\n/'
1
2
3
4
5
6
在原有的每行后方添加一个空白行
方法一:把原来的行替换成&\n
[root@web01 tmp]# cat a
1
2
3
4
5
6
7
[root@web01 tmp]# sed 's/^.*$/&\n/' a
1
2
3
4
5
6
7
方法二:使用G
[root@web01 tmp]# cat a
1
2
3
4
5
6
7
[root@web01 tmp]# sed 'G' a
1
2
3
4
5
6
7
显示最后一行的行号
记得加-n
[root@web01 tmp]# cat a6
1
2
3
5
6
[root@web01 tmp]# sed '$=' a6
1
2
3
5
6
6
[root@web01 tmp]# sed '$=' a6 -n
6
显示所有行的行号,但空行不显示行号
思路:使用排除命令 !
和=
打印行号,空行不打印行号
注意:这里不能把空行直接删掉,因为行号就不对了
[root@web01 tmp]# cat a6
1
2
3
5
6
[root@web01 tmp]# sed '/^$/!=' a6 -n
1
2
3
5
6
在查找到的行前面增加一个空行
对于这种想在查找到的行前面or后面增加一些东西的,可以使用&
这里查找到2,在它前面增加一个空行
[root@web01 tmp]# cat a
1
2
3
4
5
6
7
[root@web01 tmp]# sed 's/2/\n&/' a
1
2
3
4
5
6
7
统计文本的行数
其实输出最后一行行号就行
[root@web01 tmp]# cat a5
1
2
3
4
5
6
[root@web01 tmp]# sed a5 '$='
sed: can't read $=: No such file or directory
[root@web01 tmp]# sed '$=' a5 -n
10
将每一行行首的空白字符删掉
思路:空白字符包括空格和制表符,必须两个都要删掉,直接删空格是不行的,要把\t
的也删了,不然制表符删不了
注意:|
如果使用-r,那么|
前面不用换行符,如果没有使用-r ,那么必须要用换行符
[root@web01 tmp]# cat a7
1
2
3
4
5
[root@web01 tmp]# sed 's/^ *\|^\t*//g' a7
1
2
3
4
5
[root@web01 tmp]# sed 's/^ *|^\t*//g' a7 -r
1
2
3
4
5
[root@web01 tmp]# sed 's/^ *\|^\t*//g' a7 -r
1
2
3
4
5
将文本中的aaa,bbb都替换成ttt
使用|
就行
[root@web01 tmp]# cat a8
1aaa
2
3
bbb4
aaa
aaa bbb
[root@web01 tmp]# sed -r 's/aaa|bbb/ttt/g' a8
1ttt
2
3
ttt4
ttt
ttt ttt
将yes替换成no,并且只在行中没有hello的情况下
使用!
排查命令
[root@web01 tmp]# cat a9
yes hello
yes
[root@web01 tmp]# sed '/.*hello.*/!s/yes/no/' a9
yes hello
no
将每行的字符逆序显示(保持空间)
awk练习
1.只处理用户ID为奇数的行,并打印用户名和uid号
[root@web01 tmp]# awk -F: '$3%2==1 {print $1,$3}' /etc/passwd
bin 1
adm 3
sync 5
halt 7
operator 11
nobody 99
dbus 81
polkitd 999
postfix 89
zijian 1001
nginx 499
rpcuser 29
mysql 27
tss 59
使用if
[root@web01 tmp]# awk -F: '{
if ($3%2==1)
{
print $1,$3;
}
}' /etc/passwd
2.显示系统的普通用户(uid>500),并打印用户名和ID
awk '$3>500 {print $1}' /etc/passwd
[root@web01 tmp]# awk -F: '$3>500 {print $1}' /etc/passwd
polkitd
chrony
suzijian
zijian
elasticsearch
nfsnobody
3.显示用户shell是’/bin/bash’的用户,并打印用户名
awk -F: '/\/bin\/bash/ {print $1}' /etc/passwd
4.统计普通用户的个数
awk -F: '$3>500 {i++} END{print i}' /etc/passwd
5.统计文本的总行数
NR是已处理的输入记录数
FNR是当前数据文件的数据行数
awk -F: 'END{print NR}' /etc/passwd
awk -F: 'END{print FNR}' /etc/passwd
6.显示文件名
这里记得要加END,否则文件有多少行,就输出几次FILENAME
awk -F: 'END {print FILENAME}' /etc/passwd
7.显示UID为501用户的相关信息
awk -F: '$3==501 {print $0}' /etc/passwd
8.利用awk模拟tail -1的效果
9.看懂数组两个练习(统计tcp链接数)
awk 'END {print $0}' /etc/passwd
10.将test2文件中的行追加到test1的同一行后,并保存到文件test3
统计tcp的链接数
这类问题是,怎么统计每一列出现的次数,一定要会,非常基础
记得使用/t
的话要加双引号
netstat -ant | awk '/^tcp/{++state[$NF]} END {for(key in state) print key "\t" state[key]}'
输出结果
LISTEN 5
ESTABLISHED 7
统计访问日志中每个ip访问的次数
awk '{ips[$1]++} END {for (i in ips) print i ,ips[i]}' /usr/local/nginx/logs/access.log
找出访问日志中访问前10的ip(重要)
很重要
awk '{ips[$1]++} END{for(i in ips){print i,ips[i]} }' /usr/local/nginx/logs/access.log |sort -k2 -rn
我这里只访问了两次
结果:120.231.156.54 2