[toc]
sed命令简介
sed处理时,有2个缓冲区:【pattern space】和【hold space】
sed执行过程:
先读入一行,去掉尾部换行符,存入【pattern space】,执行编辑命令。
处理完毕,除非加了-n参数,把现在的【pattern space】打印出来,在后边打印曾去掉的换行符。
把【pattern space】置空。 接着读下一行,处理下一行。
sed的默认输出:【pattern space】里的内容输出到标准输出。
sed的常用选项:
-
【pattern space】里的内容不输出到标准输出:-n
-
默认只能执行一个脚本,执行多个脚本:-e script, --expression=script
可以有多个-e script
-
如果要执行的脚本特别多,可以指定一个脚本文件:-f /path/to/sed_scirpt
脚本文件里,每行一个编辑命令。
-
支持使用扩展的正则表达式,默认是基本正则表达式:-r
-
直接编辑原文件:-i
-
把【pattern space】空间中的内容覆盖到【hold space】空间:h
-
把【pattern space】空间中的内容追加到【hold space】空间,然后删除【pattern space】空间中的内容:H
-
把【hold space】空间中的内容覆盖到【pattern space】空间:g
-
把【hold space】空间中的内容追加到【pattern space】空间,然后删除【hold space】空间中的内容:G
-
互换【hold space】【pattern space】里的内容:x
-
把匹配到的行的下一行放入【pattern space】,并把匹配到的行删除掉:n
-
把匹配到的行的下一行放入【pattern space】,不删除匹配到的行:N
-
删除【pattern space】空间中的行:d
-
删除多行模式下【pattern space】里的所有行。(比如用N了,【pattern space】里就有多行):D
编辑命令:
如果有多个命令,则用分号分隔。
删掉【pattern space】里的内容:d
删除start.sh的第二行到第六行。
1# nl start.sh | sed '2,6d'
21 #!/bin/sh
37 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
48 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
59 > /dev/null 2>&1 &)
610 /dev/null 2>&1
711 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
812 java -Dio.netty.leakDetectionLevel=ADVANCED \
913 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
1014 /home/htga/docker/docker/trunk/target/docker/docker.jar \
1115 com.hitotek.docker.DockerApplication 1000 &)
1216 /dev/null
在行前插入:-i \text 支持使用\n实现多行插入
1# nl start.sh | sed '3i \new line\nother line'
2
31 #!/bin/sh
42 set -xv
53 basepath="$( cd "$(dirname "$0")"&& pwd )"
6new line
7other line
84 echo $basepath
95 $(nohup java )
106 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
117 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
128 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
139 > /dev/null 2>&1 &)
1410 /dev/null 2>&1
1511 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
1612 java -Dio.netty.leakDetectionLevel=ADVANCED \
1713 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
1814 /home/htga/docker/docker/trunk/target/docker/docker.jar \
1915 com.hitotek.docker.DockerApplication 1000 &)
2016 /dev/null
在行后插入:-a \text 支持使用\n实现多行插入
1# nl start.sh | sed '3a \new line\nother line'
2
31 #!/bin/sh
42 set -xv
5new line
6other line
73 basepath="$( cd "$(dirname "$0")"&& pwd )"
84 echo $basepath
95 $(nohup java )
106 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
117 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
128 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
139 > /dev/null 2>&1 &)
1410 /dev/null 2>&1
1511 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
1612 java -Dio.netty.leakDetectionLevel=ADVANCED \
1713 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
1814 /home/htga/docker/docker/trunk/target/docker/docker.jar \
1915 com.hitotek.docker.DockerApplication 1000 &)
2016 /dev/null
21
22# nl start.sh | sed '/java/a \#java被修改的'
替换行:-c \text 把匹配到的行,替换成text
1# nl start.sh | sed '/java/c \#java被修改的'
2
31 #!/bin/sh
42 set -xv
53 basepath="$( cd "$(dirname "$0")"&& pwd )"
64 echo $basepath
7#java被修改的
8#java被修改的
97 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
108 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
119 > /dev/null 2>&1 &)
1210 /dev/null 2>&1
13#java被修改的
14#java被修改的
1513 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
1614 /home/htga/docker/docker/trunk/target/docker/docker.jar \
1715 com.hitotek.docker.DockerApplication 1000 &)
1816 /dev/null
19
####保存匹配到的行,到指定文件中:-w ./sedw.txt
把带Java的行,保持到/tmp/fsnew
1# nl start.sh | sed -n '/java/w ./sedw.txt'
2
3[root@localhost testsed]# ls
4sedw.txt start.sh testSed.sh test.txt
5[root@localhost testsed]# cat sedw.txt
65 $(nohup java )
76 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
811 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
912 java -Dio.netty.leakDetectionLevel=ADVANCED \
在匹配到的行的上一行,加上行号:=
在以java的行的上一行加上行号
1# nl start.sh | sed '/java/='
2
3[root@localhost testsed]# nl start.sh | sed '/java/='
4 1 #!/bin/sh
5 2 set -xv
6 3 basepath="$( cd "$(dirname "$0")"&& pwd )"
7 4 echo $basepath
85
9 5 $(nohup java )
106
11 6 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
12 7 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
13 8 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
14 9 > /dev/null 2>&1 &)
15 10 /dev/null 2>&1
1611
17 11 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
1812
19 12 java -Dio.netty.leakDetectionLevel=ADVANCED \
20 13 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
21 14 /home/htga/docker/docker/trunk/target/docker/docker.jar \
22 15 com.hitotek.docker.DockerApplication 1000 &)
23 16 /dev/null
匹配到的行不执行后面的命令;没匹配到的行执行后面的命令:!。注意:!处理命令之前。
删除不以#开头的行:
1# nl start.sh | sed '/^#/!d' /etc/fstab
2#
3[root@localhost testsed]# nl start.sh | sed '/java/!d'
4 5 $(nohup java )
5 6 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
6 11 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
7 12 java -Dio.netty.leakDetectionLevel=ADVANCED \
8
查找替换:
- s/要替换的/替换成的/替换标记。它的分隔符/可以自己指定,常用的有s@@@,s###
替换标记:
- 全局替换:g
- 将替换成功的结果保存到文件:w /path/to/save
- 显示替换成功的行:p
练习
1,删除test文件中所有以空白字符开头的行的行首的所有空白字符
1# nl start.sh | sed 's@^[[:space:]]\+@@'
2
31 #!/bin/sh
42 set -xv
53 basepath="$( cd "$(dirname "$0")"&& pwd )"
64 echo $basepath
75 $(nohup java )
86 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
97 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
108 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
119 > /dev/null 2>&1 &)
1210 /dev/null 2>&1
1311 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
1412 java -Dio.netty.leakDetectionLevel=ADVANCED \
1513 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
1614 /home/htga/docker/docker/trunk/target/docker/docker.jar \
1715 com.hitotek.docker.DockerApplication 1000 &)
1816 /dev/null
2,删除包含java的行 和 config 的行
1# nl start.sh | sed -e 's@java@@' -e '/config/d'
2 1 #!/bin/sh
3 2 set -xv
4 3 basepath="$( cd "$(dirname "$0")"&& pwd )"
5 4 echo $basepath
6 5 $(nohup )
7 6 $(nohup -Dio.netty.leakDetectionLevel=ADVANCED \
8 8 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
9 9 > /dev/null 2>&1 &)
10 10 /dev/null 2>&1
11 12 -Dio.netty.leakDetectionLevel=ADVANCED \
12 14 /home/htga/docker/docker/trunk/target/docker/docker.jar \
13 15 com.hitotek.docker.DockerApplication 1000 &)
14 16 /dev/null
sed的常用查询方式
1、不给地址:对全文进行处理
- nl start.sh |sed 'p'
11 #!/bin/sh
21 #!/bin/sh
32 set -xv
42 set -xv
53 basepath="$( cd "$(dirname "$0")"&& pwd )"
63 basepath="$( cd "$(dirname "$0")"&& pwd )"
74 echo $basepath
84 echo $basepath
95 $(nohup java )
105 $(nohup java )
116 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
126 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
137 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
147 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
158 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
168 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
179 > /dev/null 2>&1 &)
189 > /dev/null 2>&1 &)
1910 /dev/null 2>&1
2010 /dev/null 2>&1
2111 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
2211 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
2312 java -Dio.netty.leakDetectionLevel=ADVANCED \
2412 java -Dio.netty.leakDetectionLevel=ADVANCED \
2513 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
2613 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
2714 /home/htga/docker/docker/trunk/target/docker/docker.jar \
2814 /home/htga/docker/docker/trunk/target/docker/docker.jar \
2915 com.hitotek.docker.DockerApplication 1000 &)
3015 com.hitotek.docker.DockerApplication 1000 &)
3116 /dev/null
3216 /dev/null
33
- nl start.sh |sed -n 'p'
11 #!/bin/sh
22 set -xv
33 basepath="$( cd "$(dirname "$0")"&& pwd )"
44 echo $basepath
55 $(nohup java )
66 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
77 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
88 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
99 > /dev/null 2>&1 &)
1010 /dev/null 2>&1
1111 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
1212 java -Dio.netty.leakDetectionLevel=ADVANCED \
1313 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
1414 /home/htga/docker/docker/trunk/target/docker/docker.jar \
1515 com.hitotek.docker.DockerApplication 1000 &)
1616 /dev/null
2、单地址
- #:指定行
1nl start.sh |sed -n '1p'
2输出匹配的第一行
31 #!/bin/sh
4
- /pattern/:被此模式所匹配到的每一行
1 nl start.sh |sed -n '/java/p'
2输出匹配的java的行
35 $(nohup java )
46 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
511 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
612 java -Dio.netty.leakDetectionLevel=ADVANCED \
7
3,地址范围
- $:最后一行
1nl start.sh |sed -n '$p'
216 /dev/null
- #,#:起始和结束
1nl start.sh |sed -n '3','5p' 或者 nl start.sh |sed -n '3','5'p
23 basepath="$( cd "$(dirname "$0")"&& pwd )"
34 echo $basepath
45 $(nohup java )
- #,+#:起始,和从起始加多少行
1nl start.sh |sed -n '3','+5p' 或者 nl start.sh |sed -n '3','+5'p
23 basepath="$( cd "$(dirname "$0")"&& pwd )"
34 echo $basepath
45 $(nohup java )
56 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
67 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
78 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
- #,/pat1/:起始到,pat1匹配到的行
1nl start.sh |sed -n '3','/docker/p' 或者 nl start.sh |sed -n '3','/docker/'p
2
33 basepath="$( cd "$(dirname "$0")"&& pwd )"
44 echo $basepath
55 $(nohup java )
66 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
77 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
8
- /pat1/,/pat2/:pat1匹配到的行,到pat2匹配到的行
1nl start.sh |sed -n '/nohup/','/ADVANCED/'p 或者 nl start.sh |sed -n '3','/ADVANCED/'p
25 $(nohup java )
36 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
411 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
512 java -Dio.netty.leakDetectionLevel=ADVANCED \
4,步进:a~b
a为初始值 b为 步数
- 1~2:1,3,5,7,9.。。行(所有奇数行)
1nl start.sh |sed -n '1~2'p
2
31 #!/bin/sh
43 basepath="$( cd "$(dirname "$0")"&& pwd )"
55 $(nohup java )
67 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
79 > /dev/null 2>&1 &)
811 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
913 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
1015 com.hitotek.docker.DockerApplication 1000 &)
11
- 2~2:2,4,6,8,10.。。行(所有偶数行)
1nl start.sh |sed -n '2~2'p
22 set -xv
34 echo $basepath
46 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED \
58 /home/htga/docker/docker/trunk/target/docker/docker.jar com.hitotek.docker.DockerApplication 1000 \
610 /dev/null 2>&1
712 java -Dio.netty.leakDetectionLevel=ADVANCED \
814 /home/htga/docker/docker/trunk/target/docker/docker.jar \
916 /dev/null
sed比较复杂的例子
+ 取出最后一行:
1# nl start.sh | sed '$!d' 或 nl start.sh | sed -n '$p'
2
3[root@localhost testsed]# nl start.sh | sed '$!d'
4 16 /dev/null
5[root@localhost testsed]# nl start.sh | sed -n '$p'
6 16 /dev/null
- 第一种解释:
- 1-15行不是最后一行 ($ 最后一行 ) 执行到 $ 条件不满足
- !条件不满足的时候 反而要执行
- 执行d (删除 pattern space 输出 pattern space时为空)
- 16行 执行到 $ 条件满足
- !条件满足的时候 不执行
- 不执行d
- 输出 pattern space 即 16行
- 第二种的解释
- 1-15行不是最后一行 ($ 最后一行 ) 执行到 $ 条件不满足
- 条件不满足的时候 不执行p 即 pattern space 有1-15行数据
- 16行 执行到 $ 条件满足
- 条件满足的时候 执行p 输出 16行数据
- -n 参数 不输出 pattern space 即 16行
显示奇数行:
1# nl start.sh | sed -n 'p;n' 或者 nl start.sh | sed -n '1~2p'
2 1 #!/bin/sh
3 3 basepath="$( cd "$(dirname "$0")"&& pwd )"
4 5 $(nohup java )
5 7 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker & -Xms256m -Xmx512m -classpath \
6 9 > /dev/null 2>&1 &)
7 11 $(nohup java -Dio.netty.leakDetectionLevel=ADVANCED -Dglobal.config.path=$basepath -Xms256m -Xmx512m -classpath $basepath/docker.jar com.hitotek.docker.DockerApplication 1000 > /dev/null 2>&1 &)
8 13 -Dglobal.config.path=/home/htga/docker/docker/trunk/target/docker -Xms256m -Xmx512m -classpath \
9 15 com.hitotek.docker.DockerApplication 1000 &)
-
p: pattern space 这行 复制到 hold space
-
n:把要操作的行 往下一行 ;
执行流程解释
读入第一行 pattern space
执行p 把第一行的数据 直接输出
执行n 把第二行的【pattern space】数据删除 读入第三行的数据到 pattern space
没有 -n 再次输出第一行
执行p 把第三行的数据 直接输出
执行n 把第四行的【pattern space】数据删除 读入第五行的数据到 pattern space
没有 -n 再次输出第三行
执行p 把第五行的数据 直接输出
执行n 把第六行的【pattern space】数据删除 读入第七行的数据到 pattern space
没有 -n 再次输出第五行
………………
执行p 把第十五行的数据 直接输出
执行n 把第十六行的【pattern space】数据删除
复杂查询特定连续几行:
1cat start.sh |
2 sed /^#/d |
3 sed -n '/nohup/{
4 p;
5 /.*&.*/b endPo;
6 :a;
7 n;
8 p;
9 /.*&.*/!b a;
10 :endPo;
11 }' |
12 sed -n '/nohup.*/{
13 /\\/!b endPo;p;
14 :a;n;
15 p;
16 /\\/b a;
17 :endPo;
18 }'
- -n 只会输出匹配的行
- ^特定开头
- d 删除
- p输出
- b 跳跃某个节点
- :a 指定a 节点
- n 读下一行,并删除当前【pattern space】里的内容后,再把下一行的内容放入【pattern space】
其他相关例子
1 1,显示偶数行:
2 nl start.sh | sed -n 'n;p'
3 2,倒置文本:
4 nl start.sh | sed '1!G;h;$!d'
5
6 nl start.sh | sed 'G'
graph LR
A["[]矩形"]-->|"-->箭头"|B("()圆角")
B---|"---连线"|C(("双(())圆形"))
C==>|==粗线|D{"{}菱形"}
C-->E>">]为非对称"]