sed 快速上手
能够像打印机一样,对文件的文本进行处理。因此,相当于行处理器。
包括以下场景:
- 使用脚本指令编辑文件
- 编辑多个文件
- 简化对文件的重复操作
- 对文件内容进行固定规则转换
基本语法
sed [option] [脚本命令] [file]
option 选项
命令参数 options:
- -n:取消默认的输出。只显示匹配出来的行。
- -e:命令行给出多个 sed 指令时使用。
- -i:直接将处理结果写入文件
- -f:从文件中读取 sed 要进行的操作
- -r:使用拓展正则表达式。
例子1
将文件的第一行和最后一行写入到另一个文件之中。
sed -n '1,$w 2.txt' 1.txt
相当于
sed -n -e '1w 2.txt' -e '$w 2.txt' 1.txt
使用 -e
选项的好处,还在于同时可以写入到多个不同的文件之中。
sed -n -e '1w 2.txt' -e '$w 3.txt' 1.txt
例子2
打印显示 root 开头的行。
使用正则拓展,并且控制输出。
sed -rn '/^root/p' /etc/passwd
例子3
搜索替换指定单词。
使用 i
选项将会更新源文件的行内容,因此尽量慎用。
除了更新文本外,批量更新一些功能脚本时,是非常好用的。
sed -i 's/user/newuser/g' /etc/passwd
脚本命令标签
在脚本命令选项之中,通常的格式如下:
[脚本命令]
'标志/匹配/命令标签'
常用的命令标签包括如下:
-
a:新增行
-
c:取代行
-
d:删除行
-
i:插入行
-
s:取代
-
p:打印行
-
q:退出 sed
-
!:反向,对匹配行以外的所有行进行操作
-
s:替换标志
-
g:全局替换
-
i:忽略大小写
-
r:从文件中读取
-
w:将行写入到文件中
-
y:将字符转换为另一个字符
-
h:清除保持空间的内容后,把模式空间里的内容复制到保持空间
-
H:把模式空间里的内容追加到保持空间
-
g:清除模式空间的内容后, 取出保持空间的内容,并复制到模式空间
-
G:取出保持空间的内容,追加在模式空间原有内容的后面
-
x:交换模式空间与保持空间的内容
这里需要注意,正则本身也会带有有一些符号操作,通常用两个斜杠的方式进行使用。
正则的作用是用来匹配行,脚本命令中,正则表达式和命令标签为前后关系,如果中间有数字的话,需要用逗号隔开,如下:
例子4
# 删除全部
sed -r '/regx/ d' file
# 删除以下5行
sed -r '/regx/,5 d' file
# 含有root的行不删除,其他都删除
sed -r ' /root/ !d ' file
# 奇数行删除,其实就是匹配到行号除以2,余数是1的行
sed -r ' 1~2 d '
脚本命令格式
脚本命令格式如下:
x:x 为行号
x,y:表示行号从 x 到 y
/pattern:匹配模式
/pattern /pattern:查看包含两个模式
pattern/ ,x:给定行号进行查询操作
x,/pattern/:用行号和模式查询匹配行
x,y!:查询不包含指定行号的行
更多例子
打印头两行
sed '2q' test.file
替换指定内容
sed -i 's/新内容/要替换内容/g' file.txt
增加操作,在testfile文件的第四行后添加一行,内容为 content
sed -e '4a\content' testfile
快速删除第2~5行
nl 能够将文本内容带行号输出。
nl /etc/passwd | sed '2,5d'
删除第3行到最后一行
nl /etc/passwd | sed '3,$d'
在第二行前插入文本
nl /etc/passwd | sed '2i new_insert_text'
将第2~5行的文本替换
nl /etc/passwd | sed '2,5c new_replace_txt'
只列出几行
nl /etc/passwd | sed -n '5,7p'
删除行首空格
sed 's/^[ ]*//g' filename
sed 's/^ *//g' filename
sed 's/^[[:space:]]*//g' filename
行后和行前添加新行,&代表pattern
# 行后
sed 's/pattern/&\n/g' filename
# 行前
sed 's/pattern/\n&/g' filename
使用变量替换(使用双引号)
sed -e "s/$var1/$var2/g" filename
在第一行前插入文本
sed -i '1 i\插入字符串' filename
在最后一行插入
sed -i '$ a\插入字符串' filename
在匹配行前插入
sed -i '/pattern/ i "插入字符串"' filename
在匹配行后插入
sed -i '/pattern/ a "插入字符串"' filename
删除文本中空行和空格组成的行以及#号注释的行
grep -v ^# filename | sed /^[[:space:]]*$/d | sed /^$/d
过滤 IP
ifconfig ens3 | grep 'inet' | sed 's/inet//g' | sed 's/netmask.*$//g'
更多例子
#!/bin/bash
##查文件从 32994 到 34871 行内容
sed -n '32994,34871/p' config_file
##删除文件从 32994 到 34871 行内容
sed '32994,34871/d' config_file
##替换文件中 performance_schema 改为 performance_schema_bak
sed -i "s/performance_schema/performance_schema_bak/g" config_file
##sed 去除注释行
sed -i -c -e '/^#/d' config_file
##sed 去除空行
sed -i -c -e '/^$/d' config_file
##sed 去空行和注释行
sed -i -c -e '/^$/d;/^#/' config_file
##在某字符串下面一行增加一字符串
sed -i '/fastcgi_path_info/a\fastcgi_param ENV_VAR_MY test;' test*.conf
#假设处理的文本为 test.file
#在每行的头添加字符,比如"HEAD",命令如下:
sed 's/^/HEAD&/g' test.file
#在每行的行尾添加字符,比如“TAIL”,命令如下:
sed 's/$/&TAIL/g' test.file
##替换某些后缀文件中的字符
sed -i "s/text_to_replace/replacement/g" `find . -type f -name <filename>`
sed -i "s/10.0.0.75/10.0.0.76/g" `find . -type f -name "*.properties"`
sed -i "s/10.0.0.18/10.0.0.17/g" `find . -type f -name "*.properties"`
sed -i "s/10.0.0.16/10.0.0.17/g" `find . -type f -name "*.php"`
sed -i "s/d12/111222/g" `find . -type f -name "*.properties"`
#sed 删除文件倒数 10 行 #把文件倒序
sed -i '1!G;$!h;$!d' filename
#删除 10 行
sed -i '1,10d' filename
#把文件倒序回来
sed -i '1!G;$!h;$!d' filename
nl file | tail -n 10 | awk 'NR == 1 '{print $1}'
awk 'BEGIN{CMD="wc -l file";CMD|getline i}NR<=(i-10)' file
sed -n ':a;1,10!{P;N;D;};N;ba' file