shell三剑客之–sed的用法(上)

avatar 2020年2月17日18:46:24 评论 765 次浏览

首先我们要明白sed是处理文本的,可以针对文本文件进行增、删、改、查的操作。灵活方便,特别是针对大的文本文件,有时候文件过大vim打不开,这个时候sed的作用就显示出来了。先看看sed有哪些参数,然后我们根据sed的参数做一些例子,能够看的更详细一些。

用法: sed [选项] [动作] [输入文件]...

  -n, --quiet, --silent
				 取消自动打印模式空间
  -e 脚本, --expression=脚本
				 添加“脚本”到程序的运行列表
  -f 脚本文件, --file=脚本文件
				 添加“脚本文件”到程序的运行列表
  --follow-symlinks
				 直接修改文件时跟随软链接
  -i[SUFFIX], --in-place[=SUFFIX]
				 edit files in place (makes backup if SUFFIX supplied)
  -c, --copy
				 use copy instead of rename when shuffling files in -i mode
  -b, --binary
				 does nothing; for compatibility with WIN32/CYGWIN/MSDOS/EMX (
				 open files in binary mode (CR+LFs are not treated specially))
  -l N, --line-length=N
				 指定“l”命令的换行期望长度
  --posix
				 关闭所有 GNU 扩展
  -r, --regexp-extended
				 在脚本中使用扩展正则表达式
  -s, --separate
				 将输入文件视为各个独立的文件而不是一个长的连续输入
  -u, --unbuffered
				 从输入文件读取最少的数据,更频繁的刷新输出
  -z, --null-data
				 separate lines by NUL characters
  --help
				 display this help and exit
  --version
				 output version information and exit

这是系统中sed的参数,那么多参数组合方式不一样实现的功能也不一样,所以这里就根据老方式"增删改查"。但是sed命令的组合是参数和动作,我们先说参数,然后在说动作。在没有学习sed命令之前我们先准备好我们需要的文件以及内容,第一个是用for循环写的一个简单日志

[root@www.wulaoer.org wulaoer]# for i in `seq 60`; do echo 10.10.2.$i 2020:02:14:18:$i 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36  >> access.log;done

第二个文件不需要那么多,我们只写一些关键词,我就直接创建了:

[root@www.wulaoer.org wulaoer]# cat wulaoer.txt 
nagios
python3
运维服务
 运维开发
jenkins
Django
技术博客
 mongodb
mysql
jenkins
pinpoint
zabbix
nagios
grafana
cacti
redis
ES
nginx
php
java
prometheus
apollo
nacos
spring
dubbo

使用sed查看文件

如果知道行,查看某一行的日志:

[root@www.wulaoer.org wulaoer]# sed -n '2p' access.log 
10.10.2.2 2020:02:14:18:2 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36

如果知道行,查看某一段的日志:

[root@www.wulaoer.org wulaoer]# sed -n '3,8p' access.log 
10.10.2.3 2020:02:14:18:3 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.4 2020:02:14:18:4 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.5 2020:02:14:18:5 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.6 2020:02:14:18:6 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.7 2020:02:14:18:7 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.8 2020:02:14:18:8 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36

打印文件第15行到最后一行

[root@www.wulaoer.org wulaoer]# sed -n '15,$p' access.log 
10.10.2.30 2020:02:14:18:30 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.31 2020:02:14:18:31 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.32 2020:02:14:18:32 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.33 2020:02:14:18:33 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.34 2020:02:14:18:34 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36

如果不知道行,可以根据日志中的时间,查看某一段时间的日志:

[root@www.wulaoer.org wulaoer]# sed -n '/2020:02:14:18:20/,/2020:02:14:18:22/p' access.log
10.10.2.20 2020:02:14:18:20 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.21 2020:02:14:18:21 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36
10.10.2.22 2020:02:14:18:22 200 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36

sed也支持正则,也可以根据正则查看某一段的日志:

sed -n ‘/ 2020:02:14:[0-9][0-9]:[0-9][0-9]/,/ 2020:02:14:[0-9][0-9]:[0-9][0-9]/p’  logfile

打印匹配的字符串下的多行,这里操作时已经把空格删除

[root@www.wulaoer.org wulaoer]# sed -n '/Django/,+6p' wulaoer.txt 
Django
技术博客
mongodb
mysql
jenkins
pinpoint
zabbix

打印匹配mysql到ES的行

[root@www.wulaoer.org wulaoer]# sed -n '/mysql/,/ES/p' wulaoer.txt 
mysql
jenkins
pinpoint
zabbix
nagios
grafana
cacti
redis
ES

打印文件的最后一行的行号

[root@www.wulaoer.org wulaoer]# sed -n '$=' wulaoer.txt 
25

打印匹配字符串wulaoer的行号的两种方法:

[root@www.wulaoer.org wulaoer]# sed -n '/zabbix/=' wulaoer.txt 
12
[root@www.wulaoer.org wulaoer]# cat -n wulaoer.txt | grep zabbix | awk '{print $1}'
12

打印匹配字符串吴老二的行号和内容

[root@www.wulaoer.org wulaoer]# sed -n '/zabbix/{=;p}' wulaoer.txt 
12
zabbix

sed修改文件

首先根据行修改文件,先找到行修改某一行的字符串。使用sed修改文件时用到了参数'-i',修改后不返回修改的结果,需要在文件中查看一下,这里我就使用sed命令打印修改的内容,方便查看:

把第二行的字符串200修改成499

[root@www.wulaoer.org wulaoer]# sed -i '2s/200/499/' access.log 
10.10.2.2 2020:02:14:18:2 499 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36

这里修改的是一行的第一个字符串,如果第二行有多个200字符串都修改需要使用"g",

[root@www.wulaoer.org wulaoer]# sed -i '2s/200/499/g' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '2p' access.log 
10.10.2.2 2020:02:14:18:2 499 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/499.36

找到第二行,修改两个字符串,把状态200替换成499,02替换成20:

[root@www.wulaoer.org wulaoer]# sed -i '4s/200/499/g;4s/02/20/g' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '4p' access.log 
10.10.2.4 2200:20:14:18:4 499 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/499.36

把文件的第四行到最后一行删除,然后把字符串"200"替换成"IP"

[root@www.wulaoer.org wulaoer]# sed -i '4,$d;s/200/IP/' test.txt

把第二行至第四行的内容替换成字符串www.wulaoer。

[root@www.wulaoer.org wulaoer]# sed -i '2,4c www.wulaoer.org' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '2p' access.log 
www.wulaoer.org

把第六行的内容替换成www.wulaoer.org

[root@www.wulaoer.org wulaoer]# sed -i '6c www.wulaoer.org' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '6p' access.log 
www.wulaoer.org

在第一行追加一条日志内容为https://www.wulaoer.org

[root@www.wulaoer.org wulaoer]# sed -i '1i\https://www.wulaoer.org' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '1p' access.log 
https://www.wulaoer.org

在文件的最后一行追加一条,内容为www.wulaoer.org

[root@www.wulaoer.org wulaoer]# sed -i '$a\https://www.wulaoer.org' access.log 
[root@www.wulaoer.org wulaoer]# awk 'NF{a=$0}END{print a}' access.log  #查看最后一行内容
www.wulaoer.org

以上是知道行,然后修改,如果不知道行又该如何修改呢?这个时候就需要用到关键词,下面我们继续看下面的例子:

查找关键词"10.10.2.12"所在的行,然后修改这行的字符串200替换成502,如果替换正行就在后加'g'

[root@www.wulaoer.org wulaoer]# sed -i '/10.10.2.12/s/200/502/' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '/10.10.2.12/p' access.log 
10.10.2.12 2020:02:14:18:12 502 http://www.wulaoer.org/ HTTP/1.1 Mobile Safari/200.36

查找关键字所在的行,并把nginx替换成zabbix,mysql替换成redis

[root@www.wulaoer.org wulaoer]#	sed -i '/wulaoer/ { s/nginx/zabbix/g;  s/mysql/redis/g; }'  wulaoer.txt

查找关键词"10.10.2.12"所在的行,然后在这一行下追加一行新内容,内容为:运维开发

[root@www.wulaoer.org wulaoer]# sed -i '/10.10.2.12/a\运维开发' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '/运维开发/p' access.log 
运维开发

这个是知道关键字符串,如果不知道关键字符串,可以使用正则:

[root@www.wulaoer.org wulaoer]# sed -i '/^10.*.2.13*.36$/a\运维服务' access.log 
[root@www.wulaoer.org wulaoer]# sed -n '/运维服务/p' access.log 
运维服务

'^'表示开头,'*'表示一个字符串,'$'表示结尾。这里为了下面的操作,我需要把wulaoer.txt文件进行修改一下,修改后的内容为:

[root@www.wulaoer.org wulaoer]# cat wulaoer.txt 
nagios
wulaoer
wulaoer.org ruby www.wulaoer.org
python3
运维服务
运维开发
jenkins
Django
技术博客
mongodb
mysql
jenkins
pinpoint
zabbix
nagios
grafana
cacti
redis
ES
nginx
php
java
prometheus
apollo
nacos
spring
dubbo

匹配到test.txt文件中的'wulaoer'字符串所在的行中'org'字符串替换成'技术博客'

[root@www.wulaoer.org wulaoer]# sed -i '/wulaoer/{s/org/ 技术博客/;p}' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# sed -n '1,4p' wulaoer.txt 
nagios
wulaoer
wulaoer. 技术博客 ruby www.wulaoer.org
python3

匹配到test.txt文件中的'wulaoer'字符串所在的行中'org'字符串替换成'技术博客'后就退出,然后test.txt文件匹配后的内容就清除了

[root@www.wulaoer.org wulaoer]#  sed -i '/wulaoer/{s/org/ 技术博客/;p;q}' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# sed -n '1,4p' wulaoer.txt 
nagios
wulaoer
wulaoer

把文件中的所有行合并为一行

[root@www.wulaoer.org wulaoer]# sed -n '1h;1!H;$g;s/\n/ /g;s/table/\ntable/g;$p' wulaoer.txt 
nagios wulaoer wulaoer. 技术博客 ruby www.wulaoer.org python3 运维服务 运维开发 jenkins Django 技术博客 mongodb mysql jenkins pinpoint zabbix nagios grafana cacti redis ES nginx php java prometheus apollo nacos spring dubbo 

合并上下两行

[root@www.wulaoer.org wulaoer]#  sed -n '{N; s/\n/\t/p}' wulaoer.txt 
nagios  wulaoer
wulaoer. 技术博客 ruby www.wulaoer.org  python3
运维服务        运维开发
jenkins Django
技术博客        mongodb
mysql   jenkins
pinpoint        zabbix
nagios  grafana
cacti   redis
ES      nginx
php     java
prometheus      apollo
nacos   spring
dubbo

合并三行为一行,四行就多加一个"N"

[root@www.wulaoer.org wulaoer]# sed 'N;N;s/\n/ /g' wulaoer.txt 
nagios wulaoer wulaoer. 技术博客 ruby www.wulaoer.org
python3 运维服务 运维开发
jenkins Django 技术博客
mongodb mysql jenkins
pinpoint zabbix nagios
grafana cacti redis
ES nginx php
java prometheus apollo
nacos spring dubbo

每行行首增加字符串

[root@www.wulaoer.org wulaoer]# sed -i 's/^/HEAD&/g' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# cat wulaoer.txt 
HEADnagios
HEADwww.wulaoer.org
HEADpython3

每行行尾增加字符串

[root@www.wulaoer.org wulaoer]# sed -i 's/$/&TALL/g' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# cat wulaoer.txt 
nagiosTALL
www.wulaoer.orgTALL
python3TALL
wulaoer.orgTALL

指定字符前插入字符串,也可以使用正则

[root@www.wulaoer.org wulaoer]# sed -i 's/^wulaoer/www.&/g' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# sed -n '1,4p' wulaoer.txt 
nagios
www.wulaoer
python3
www.wulaoer ruby wulaoer

在指定的字符串后面追加,可以使用正则wulaoer.*,如果想在追加的后面间隔空格在&后面加个空格即可。

[root@www.wulaoer.org wulaoer]# sed -i 's/wulaoer/&.org/g' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# sed -n '1,4p' wulaoer.txt 
nagios
www.wulaoer.org
python3
www.wulaoer.org ruby wulaoer.org

把字符串www开头的www替换成ruby

[root@www.wulaoer.org wulaoer]# sed -i 's/^www/ruby/g' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# sed -n '1,4p' wulaoer.txt 
nagios
ruby.wulaoer.org
python3
ruby.wulaoer.org ruby wulaoer.org

把文件中nagios开头的字符串追加字符串"个人技术博客"

[root@www.wulaoer.org wulaoer]# sed -i 's/nagios/&个人技术博客/g' wulaoer.txt 
[root@www.wulaoer.org wulaoer]# sed -n '1,4p' wulaoer.txt 
nagios个人技术博客
ruby.wulaoer.org
python3
ruby.wulaoer.org ruby wulaoer.org

 

以上是针对sed查看和修改操作,尽量手动操作一下,我使用的centos7操作的,我看其他的操作在我的系统上是不能实现的,这点需要注意。

 

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: