sed(Stream Editor)
流编辑器。对标准输出或文件逐行进行处理
语法格式(类似grep):sed [ -nefri ] "pattern command"
常用选项
选项:-n 只打印模式匹配行
在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
选项:-e 直接在命令行进行sed编辑,默认选项
选项:-f 编辑动作保存在文件中,指定文件执行
选项:-r 支持扩展正则表达式
选项:-i 直接修改文件内容
常用编辑命令
a ∶新增, a 的后面可以接字串,行后追加
c ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i ∶插入, i 的后面可以接字串。行前追加;
p ∶打印,亦即将某个选择的内容输出。通常 p 会与参数 sed -n 一起用
s ∶取代,可以直接进行修改工作!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g
g :在行内进行全局替换
r :外部文件读取,行后追加
第一种形式
sed [option] "pattern command " file
vim 1.txt
I love php
I love PHP
I love python
I love PYTHON
I love p.*
Hadoop is bigdata frame
1、默认sed会自带p命令、在次用p会打印两边
[root@docker-host sh]# sed "/python/p" 1.txt
I love php
I love PHP
I love python
I love python
I love PYTHON
I love p.*
Hadoop is bigdata frame
p会-n连用
[root@docker-host sh]# sed -n "/python/p" 1.txt
I love python
2、多次处理用-e
[root@docker-host sh]# sed -n -e '/python/p' -e '/PYTHON/p' 1.txt
I love python
I love PYTHON
3、处理表达式保存到文件执行 -f
vim edit.sed
/python/p
[root@docker-host sh]# sed -n -f edit.sed 1.txt
I love python
[root@docker-host sh]#
4、使用扩展表达式 -r
##不使用扩展正则表达式
[root@docker-host sh]# sed -n "/python|PYTHON/p" 1.txt
##使用扩展表达式
[root@docker-host sh]# sed -n -r "/python|PYTHON/p" 1.txt
I love python
I love PYTHON
5、直接修改文件 -i
结合 s命令用 s/love/like/g;p这种格式。命令连接处用;隔离
[root@docker-host sh]# sed -n 's/love/like/g;p' 1.txt
I like php
I like PHP
I like python
I like PYTHON
I like p.*
[root@docker-host sh]# cat 1.txt
I love php
I love PHP
I love python
I love PYTHON
I love p.*
没有加-i参数前 源文件没有变化
加上-i参数后
[root@docker-host sh]# sed -n -i 's/love/like/g;p' 1.txt
[root@docker-host sh]# cat 1.txt
I like php
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
第二种形式
stdout #标准输出 | sed [option] "pattern command"
send中的pattern详解
模式:10command 匹配到第10行
1、LineNumber ---直接指定行号
sed -n "3p" 1.txt 打印1.txt中的第三行
[root@docker-host sh]# sed -n "3p" 1.txt
I like python
模式:5,6comand 匹配从第5行开始,到第6行结束
2、StartLine,EndLine ---打印起始行号,到结束行号
sed -n "5,6p" 1.txt
[root@docker-host sh]# sed -n '5,6p' 1.txt
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]#
模式:4,+2comand 匹配从第4行开始,到第6行结束
3、StartLine,+N -----打印起始行号到,加上的行号
[root@docker-host sh]# sed -n '4,+2p' 1.txt
I like PYTHON
I like p.*
Hadoop is bigdata frame
模式:/pattern1/command 匹配到pattern1的行
----正则表达式匹配的行
[root@docker-host sh]# sed -n '/php/p' 1.txt
I like php
----用sed查找电脑中禁止登录的用户
[root@docker-host sh]# sed -n '/\/sbin\/nologin/p' /etc/passwd
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
......
......
模式:/pattern1/,/pattern2/command 匹配到pattern1行开始,到匹配到pattern2的行结束
从sshd的行到vagrant的行结束
[root@docker-host sh]# sed -n '/^sshd/,/^vagrant/p' /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:995::/var/lib/chrony:/sbin/nologin
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
[root@docker-host sh]#
模式:21,/pattern1/command 匹配从第21行开始,到匹配到pettern1行结束
[root@docker-host sh]# sed -n '21,/^vagrant/p' /etc/passwd
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:995::/var/lib/chrony:/sbin/nologin
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
模式:/pattern1/,5command 匹配到pattern1的行开始,到文本开始的第5行匹配结束
[root@docker-host sh]# sed -n '/root/,5p' /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
operator:x:11:0:operator:/root:/sbin/nologin
[root@docker-host sh]#
###从开始匹配,到文本的第三行结束来匹配图片的结果
[root@docker-host sh]# sed -n '/adm/,3p' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
结果是如果要求所在行数没有符合要求,继续向下匹配成功后返回当前行
sed编辑命令详解
编辑命令:d 删除
#### d 删除命令 、例子用的还是上文中的1.txt
[root@docker-host sh]# sed -n 'p' 1.txt
I like php
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]# sed -n '1d;p' 1.txt
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]
[root@docker-host sh]# sed -n '1,3d;p' 1.txt
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]#
删除passwd文件里面的nologin用户
[root@docker-host sh]# sed -i '/\/sbin\/nologin/d' ./passwd
编辑命令:a 追加内容行
####删除1.txt的第一行 、匹配大写PHP的行在后面追加sha
[root@docker-host sh]# sed '1d;/PHP/a sha' 1.txt
I like PHP
sha
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
编辑命令:i 之前的追加
[root@docker-host sh]# sed '/php/,/PHP/i sha' 1.txt
sha
I like php
sha
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
编辑命令:r 将后面指定文件内容追加到匹配到的行后面
vim sed.txt
First Line (11111)
Second Line (22222)
[root@docker-host sh]# sed '/python/r sed.txt' 1.txt
I like php
I like PHP
I like python
First Line (11111)
Second Line (22222)
I like PYTHON
I like p.*
Hadoop is bigdata frame
编辑命令:w将匹配到的行内容另存到其他文件中
[root@docker-host sh]# sed -n '/python/w wirte.txt' 1.txt
[root@docker-host sh]# ls wirte.txt
wirte.txt
[root@docker-host sh]#vim wirte.txt
I like python
编辑命令:s 修改
修改1.txt、改成如下内容
vim 1.txt
I like php,I really like php ,very like php
I like PHP,,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
例子
查找符合/tattern模式的字符并进行替换(加g是全局替换)
s/pattern/string/g
[root@docker-host sh]# sed 's/php/PHP_/g' 1.txt
I like PHP_,I really like PHP_ ,very like PHP_
I like PHP,,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
查找符合 s/pattern/string/2g模式的字符进行替换
2g代表从行内第二个开始替换的意思
[root@docker-host sh]# sed 's/php/_PHP/2g' 1.txt
I like php,I really like _PHP ,very like _PHP
I like PHP,,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
s/pattern/string/3gi不区分大小写,i有多重含义/*/*/是不区分大小写的
[root@docker-host sh]# sed 's/php/_PHP/3gi' 1.txt
I like php,I really like php ,very like _PHP
I like PHP,,I really like PHP ,very like _PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
编辑命令:= 显示行号
[root@docker-host sh]# sed -n '/php/=' 1.txt
1
[root@docker-host sh]#
方向引用
& 给PHP后面加上$ 。&等同于\0
[root@docker-host sh]# sed 's/php/&$/ig' 1.txt
I like php$,I really like php$ ,very like php$
I like PHP$,I really like PHP$ ,very like PHP$
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]# sed 's/php/\0$&/ig' 1.txt
I like php$php,I really like php$php ,very like php$php
I like PHP$PHP,I really like PHP$PHP ,very like PHP$PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]# echo -e "2017 2016 2018" | sed -e "s/\(.*\) \(.*\) \(.*\)/\2 \1 \3/g"
2016 2017 2018
[root@docker-host sh]#
把通过正则反向引用的方式
[root@docker-host sh]# sed 's/\(p\).p/\1ython/ig' 1.txt
I like python,I really like python ,very like python
I like Python,I really like Python ,very like Python
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
#!/usr/bin/env bash
old_str=php
new_str=PHP
sed -i "s/$old_str/$new_str/g" 1.txt
[root@docker-host sh]# sh sed_sample.sh
[root@docker-host sh]# cat 1.txt
I like PHP,I really like PHP ,very like PHP
I like PHP,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]#
如果使用单引号、需要拼接
sed -i 's/'$old_str'/'$new_str'/g' 1.txt
sed查找特定内容
配置文件代码
[myisamchk]
key_buffer_size = 20M
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
explicit_defaults_for_timestamp=true
skip-external-locking
key_buffer_size=16M
max_allowed_packet=1M
table_open_cache=64
sort_buffer_size=512K
net_buffer_length=8K
read_buffer_size=256K
read_rnd_buffer_size=512K
myisam_sort_buffer_size=8M
user=mysql
character_set_server=utf8
skip-character-set-client-handshake
lower_case_table_names=1
interactive_timeout=120
group_concat_max_len=10240
skip-external-locking
open_files_limit=65000
innodb_open_files=50000
back_log=300
max_connections=1500
max_connect_errors=100000
tmp_table_size=96M
max_heap_table_size=96M
innodb_buffer_pool_size=4096M
innodb_flush_log_at_trx_commit=1
sync_binlog=1
innodb_file_per_table=1
innodb_log_files_in_group=2
long_query_time=2
slow_query_log=1
slow_query_log_file=/usr/local/mysql/data/slow_query.log
[client]
port=3306
socket=/usr/local/mysql/mysql.sock
[mysql]
default-character-set=utf8
[myisamchk]
key_buffer_size=20M
sort_buffer_size=20M
read_buffer=2M
write_buffer=2M
[mysqlhotcopy]
interactive-timeout
注意第一个配置行【myisamchk】的配置项由于有空格、统计出了3个配置
#!/usr/bin/env bash
FILE_NAME=/home/vagrant/labs/sh/my.cnf
function get_all_segment
{
echo `sed -n '/\[.*\]/p' ${FILE_NAME} | sed -e 's/\[//g' -e 's/\]//g'`
}
function count_items_in_segment
{
items=`sed -n "/\[$1\]/,/\[.*\]/p" ${FILE_NAME} | grep -v "^#" | grep -v "^$" | grep -v "\[.*\]"`
index=0
for item in ${items}
do
index=`expr ${index} + 1`
done
echo ${index}
}
number=0
for seg in `get_all_segment`
do
number=`expr ${number} + 1`
echo "${number}:配置项:$seg 。数量:`count_items_in_segment $seg `"
done
sed删除特定内容
1d 删除第一行内容
1,10d删除1行到10行的内容
1,+5d 删除1行到6行的内容
/pattern1/d 删除每行中匹配到pattern1的行内容
/pattern1/,/pattern2/d 删除酦醅到pattern1行。直到匹配到pattern2的所有行内容
/pattern1/,10d 删除匹配到pattern1的行到第10行的所有行内容
10,/pattern1/d 删除第10行直到匹配到pattern1的所有内容
练习例子
cp /etc/passwd ./
1、删除/etc/passwd中的第15行
sed -i '15d' /etc/passwd
2、删除/etc/passwd中的第8行到第14行的所有内容
sed -i '8,14d' passwd
3、删除/etc/passwd中的不能登录的用户
sed -i '/\/sbin\/nologin/d' passwd
4、删除/etc/passwd中以mail开头的行,到以yarn开头的行的所有内容
sed -i '/^mail/,/^yarn/d' passwd
5、删除/etc/passwd中不能登录的用户,到匹配出所有符合条件的13条行记录的所有内容
sed -i '/\sbin\/nologin/,13d' passwd
6、删除/etc/passwd中第5行到以ftp开头的所有行的内容
sed -i '5,/^ftp/d' passwd
7、删除/etc/passwd中以yarn开头的行到最后行的所有内容
sed -i '/^yarn/,$d' passwd
实际案例
nginx.conf
#nginx配置文件
user vagrant;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
autoindex on;
sendfile on;
charset utf-8;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
#root /usr/local/nginx/html;
root /home/vagrant/labs/swoole;
#access_log logs/host.access.log main;
location / {
add_header Access-Control-Allow-Origin \*;
add_header Access-Control-Allow-Headers DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
if ($request_method = 'OPTIONS') {
return 204;
}
index index.php index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ .+\.php.*$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
fastcgi_param HTTPS on;
}
}
include /usr/local/openresty/nginx/conf.d/*.conf;
}
删除\#为开头的注释行
[root@docker-host sh]# sed -n '/[:blank:]*#/p' nginx.conf
打印出内容
[root@docker-host sh]# sed -n '/[:blank:]*#/p' nginx.conf
#nginx配置文件
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
#root /usr/local/nginx/html;
#access_log logs/host.access.log main;
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
[root@docker-host sh]#
删除#注释和空行
[root@docker-host sh]# sed -i '/[:blank:]*#/d;/^$/d' nginx.conf
*表示0个或多个、那么就是开头是#或者前面有多个空格的#开头的行,和空行
sed修改特定的内容
替换第一行内容old为new
1s/old/new/
替换1行到10行的内容old为new
1,10s/old/new/
替换1行到6行的内容old为new
1,+5s/old/new/
替换匹配到pattern1的行内容old为new
/pattern1/s/old/new/
替换匹配到pattern1的行直到匹到pattern2的所有行内容old为nenw
/pattern1/,/pattern2/s/old/new/
替换第10行直到匹配到pattern1的所有行内容old的为new
10,/pattern1/s/old/new/
练习例子
1、修改/etc/passwd中第1行中第一个root为ROOT
sed -i '1s/root/ROOT/g' passwd
2、修改/etc/passwd中第5行到第10行中所有的/sbin/nologin为/bin/bash
sed -i "5,10s/\/sbin\/nologin/\/bin\/bash/" passwd
3、修改/etc/passwd中匹配到/sbin/nologin的行,将匹配到行中的login改为大写的LOGIN
sed -i "/\/sbin\/nologin/s/login/LOGIN/g" passwd
4、修改/etc/passwd中批到以root开头的行,到匹配到行中包含mail的所有行。
讲这些所匹配到的行中的bin换成HADOOP
sed -i '/^root/,/mail/s/bin/HAOOP/g' passwd
5、修改/etc/passwd中从匹配到以root开头的行,到第15行中的所有行。把nologin改成SPARK
sed -i '/^root/,15s/nologin/SOARK/g' passwd
sed追加内容用法
a 在匹配行后面追加
1、a
(1)、passwd文件第10行后面追加"Add Line Behind"
sed -i '10a Add Line Behind' passwd
(2)、passwd文件第10行到第20行,每一行后面都追加"Test Line Behind"
sed -i '10,20a test Line Begind' passwd
(3)、passwd文件匹配到/bin/bash的行后面追加"Insert Line For /bin/bash Behind"
sed -i '/\/bin\/bash/a Insert Line For /bin/bash Begind' passwd
i 在匹配行前面追加
2、i
(1)、passwd文件匹配到以mail开头的行,在匹配行前追加"Add Line Before"
sed -i '/^mail/i Add Line Before' passwd
(2)、passwd文件每一行前面都追加"Insert Line Before Every Line"
sed -i 'i Insert Line Before Every Line' passwd
r 将后面指定文件内容追加到匹配到的行后面
3、r
(1)、将/etc/fatab文件的内容追加到passwd文件的第20行后面
sed -i '20r /etc/fstab' passwd
(2)、将/etc/inittab文件内容追加到passwd文件匹配/sbin/nologin行的后面
sed -i '/\/sbin\/nologin/r /etc/inittab' passwd
(3)、将/etc/vconsole.conf文件内容追加到passwd文件中特定行后面,
匹配以mail开头的行,到第18行的所有行
sed -i '/^mail/,18r /etc/vconsole.conf' passwd
w 将匹配到的行内容另存到其他文件中
4、w
(1)、将passwd文件匹配到/bin/bash的行追加到/tmp/sed.txt文件中
sed -i '/\/bin\/bash/w sed.txt' passwd
(2)、将passwd文件从第10行开始,到匹配到rpc开头结束的的所有行内容追加到
/tmp/sed-1.txt
sed -i '10,/^rpc/w sed.txt' passwd