sed教程
sed教程
sed是linux中,常用的文档替换工具。本文包含一些常见的Sed命令。大致,Sed的命令形式,地址限制(可选) + 命令。地址,1、数字,2、正则。命令如下。,
替换 s/查找的内容/替换后的内容/ 如果一行后,需要匹配多个替换,添加g
删除 1d
修改 2c some new things.
插入 2a some new things. 或 2i some new things.
3、分隔,一般使用空格分隔,有些情况下可以省略。
参考资源
常用的代码
sed,核心的操作,有删除d、插入i(a)、修改c等。结合正则、数字等匹配位置。
# 全局替换,将a替换为b。g表示全局替换 -i 表示保存文件
sed -i "s/a/b/g" test.txt
# 指定行数修改,空格分隔(或多个)
sed -i "5c helloword" a.txt
# 增加新行,即在第5行后增加。
sed -i "5a zhangsan" a.txt
# 根据文件夹的后缀来替换pro.jar
sed -i "s/pro.jar/`ls |grep.sh$`/g" run.sh
# 打印5到10行的内容 -n参数 表示仅显示处理后的结果。
sed -n "5,10p" a.txt
# 将每行复制3次。
sed -e 'p' -e 'p' test.txt
# 查找指定内容,进行替换 \n插入新行。
# 如果一行匹配到两处,也仍然只插入一次。 /se/d 匹配到则删除。
sed -i '/se/a oneoneone\ntwotwotwo' test.txt
# 利用数字,正则来匹配位置
# 1、利用数字,第1、2行进行匹配
sed "1,2 s/^/#/g" /etc/hosts
# 2、利用正则来匹配位置,即fe开头的行,进行匹配替换
sed "/^fe/ s/^/#/g" /etc/hosts
# 其他常用的命令
# G用来增加空行
sed "G;G;G" test.txt
删除注释提示:
好处是,能删除那些友善的提示,减少干扰,能更加直观的查看想看到的内容。
sed "/^\s*#/d" /etc/httpd24/httpd.conf
删除注释、空白行
更精简。
sed -e "/^\s*#/d" -e "/^\s*$/d" nginx.conf | cat -n
上面不能正确的保留到行数。下面这个正好相反。
cat -n /etc/httpd24/httpd.conf | sed "/^\s*[0-9]\+\s*#/d"
#或者
cat -n /etc/httpd24/httpd.conf | sed "/^.......\s*#/d"
删除注释
sed 's|//.*||g' hello.cpp
添加注释
# 行号3〜5之前添加注释
sed '3,5 s/^/#/' hello.sh
php添加扩展
Sed地址范围
Sed默认默认在所有的行上面操作,但是可以通过地址,来限制,在特定的行上来操作。对地址范围,有两种表示方法,一种是数字,明确的行数,另外一种,正则表达式 即/some/形式。 地址+命令,下文即以简单的p命令来操作。
以下命令形式,除了简单的p命令,其他的替换命令 s i c等都可以用。
大致可以想到,Sed的命令形式,地址限制(可选) + 命令
数字形式
#文本内容 ext = 134 hello = zhangsan good =2 say hello world. #操作命令 #1 基本操作 sed -n "1 p" test.txt #输出ext = 134 #2 逗号,表示从哪到哪 sed -n "1,3 p" test.txt #输出从1到3行。 #3 m,+n ,表示从m行开始,的后续n行。 sed -n "1,+1 p" test.txt #4 m~n 表示一个等差的行数,m m+n m+2n m+3n,如n=2时,每隔一行。 sed -n "1~2 p" test.txt #5 $表示最后一行 sed -n "2,$ p" test.txt #打印第2到最后一行。 # 在文件最后添加一行。$表示最后一行,a表示添加操作,后面的是内容。3个部分用 # 空格进行分隔。$a直接写,会报错。 sed "$ a some good add" test.txt正则形式
分隔符除了用 / 可以用竖线 | 。这样在路径替换的时候 就不用转义。
#输出包含ext的行,可能有多行
sed -n "/ext/p" test.txt
# 输出从哪到哪
sed -n "/ext/,/hello/p" test.txt
#配合,+符号 同上
sed "/ext/,+1a suchuanchao" test.txt
# 其他组合方式,待尝试
正则表达式
注意,sed的多次匹配部分需要加,
开始行^
行尾 $
单个字符 。
配置字符集合 [] 如[ab]
独有集[^] 如[~]
字符范围 [-]
零到一次出现 ?
一次或多次出现 +
零或多次出现 *
n个重复 {n}
最少出现n个 {n,}
M到N次出现 {m,n}
管道 (|)
字符转义
转移 \
分隔符号
sed 's/a/b/g' <<< "haha"
sed 's_a_b_g' <<< "haha"
sed 's#a#b#g' <<< "haha"
sed 's$a$b$g' <<< "haha"
sed 's?a?b?g' <<< "haha"
sed 's*a*b*g' <<< "haha"
sed 's-a-b-g' <<< "haha"
sed 's.a.b.g' <<< "haha"
sed 'sXaXbXg' <<< "haha"
sed 'sxaxbxg' <<< "haha"
sed 's1a1b1g' <<< "haha"
我们发现,好像任意字符都能成为符号。如果分隔符号出现了,那么应该转义。示例
$sed 'saaabag' <<< "haha"
sed: -e expression #1,char 5: unknown option to `s'
$sed 'sa\aabag' <<< "haha"
hbhb
模式空间、保持空间
https://blog.csdn.net/wanglelelihuanhuan/article/details/51591809
- g:[address[,address]]g 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除。
- G:[address[,address]]G 将hold space中的内容append到pattern space\n后。
- h:[address[,address]]h 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除。
- H:[address[,address]]H 将pattern space中的内容append到hold space\n后。
- d:[address[,address]]d 删除pattern中的所有行,并读入下一新行到pattern中。
- D:[address[,address]]D 删除multiline pattern中的第一行,不读入下一行。
- x:交换保持空间和模式空间的内容。
一般用得比较多的就是模式空间,/partern/。
例子:
# 倒序输入 模式最后1行里面,是这样的 5\n4\n3\n2\n1\n
seq 1 5|sed '1!G;h;$!d'
感觉比较难,待研究。
难懂的代码
- 标签:a、回退b
sed ':a;N;$!ba;s/a/A/g' file
- :a 创建一个labela
- N 将下一行读入到模式空间
- $! 如果不是最后一行,ba跳转到label a处
- s/a/A/ 替换a为A,只替换一次
有步骤1-3(即:a;N;$!ba;)就是为了将file全部内容读到模式空间中,然后再进行替换,这样替换就只会做一次。
实际上,没有起作用。
sed之更换某一行的内容
场景:希望替换掉某一行的内容,想用行数来操作,而非s#原始内容#新内容#g,建议的方式,2d;3i新内容这种格式。需要注意的是2d;2a新内容中种格式吧,因为已经删除掉了,无法在append进去。而2a1234;2d这种格式,它貌似无法正确的识别结尾。
[root@scc ldap2mysql]# seq 1 10 > test.txt
[root@scc ldap2mysql]# cat test.txt
1
2
3
4
5
6
7
8
9
10
[root@scc ldap2mysql]# sed -i '2d;3a12345678' test.txt
[root@scc ldap2mysql]# cat test.txt
1
3
12345678
4
5
6
7
8
9
10
[root@scc ldap2mysql]# seq 1 10 > test.txt
[root@scc ldap2mysql]# sed -i '2d;2a1234' test.txt
[root@scc ldap2mysql]# cat test.txt
1
3
4
5
6
7
8
9
10
[root@scc ldap2mysql]# seq 1 10 > test.txt
[root@scc ldap2mysql]# sed -i '2a1234;2d' test.txt
[root@scc ldap2mysql]# cat test.txt
1
2
1234;2d
3
4
5
6
7
8
9
10
[root@scc ldap2mysql]# sed -i '2d;3i1234^Ctest.txt
[root@scc ldap2mysql]# seq 1 10 > test.txt
[root@scc ldap2mysql]# sed -i '2d;3i1234' test.txt
[root@scc ldap2mysql]# cat test.txt
1
1234
3
4
5
6
7
8
9
10