两个常用的基本选项
-n
: quiet模式,默认情况下,sed会打印执行所有动作后文本的全部内容,加上-n
后,仅显示有命令处理的相关行-e
: 指定一个sed要执行的动作(命令),如果只有一个命令,可以不写,有多个命令要执行时,分别都用-e
指定,需要注意, 如果不用-e
指定命令,sed
命令会自动将后面紧跟的一个参数当做命令处理,可能对其他选项有影响,所以最好明确使用-e
选项来指定输入命令(动作)。-f
: 指定命令集文件,如果要执行的动作比较多,如何写在命令行,就需要多个-e
选项来指定。也可以直接使用-f
指定动作文件,从文件中批量获取执行动作。比较方便。-i
: 直接在文件上修改,而不是仅显示预览效果,会对文件产生修改,一般先预览,确认后可以在加该参数。-i[SUFFIX]
: -i参数后面可以跟一个扩展,会额外将输入文件复制一个备份,备份文件的名称为 ”源文件名+SUFFIX“,如-i.bak
。-r or -E
: 启用扩展正则表达式语法。sed的命令本身支持正则表达式,默认使用基本正则表达式(BRE)语法,使用-r
后表示启用扩展正则表达式(ERE)语法, 在BRE中,一些常见的元字符如+
、?
、|
等没有特殊含义,需要使用转义符\
来表示它们的特殊含义。 在ERE中,元字符具有特殊含义,如+
表示一个或多个、?
表示零个或一个、|
表示逻辑或等。使用时需要注意。-s
: 分别处理每个输入文件,而不是将它们视为单个连续的流。
输入源
sed
命令可以从文件或标准输出中获取源,默认是当做流处理的。
文件:可以从单个文件,也可以从多个文件
1
2
3
sed 's/foo/bar/' file1.txt file2.txt file3.txt # 默认当做一个输入流处理
sed 's/foo/bar/' -s file1.txt file2.txt file3.txt # 独立处理每个文件
sed 's/foo/bar/' *.txt # 支持通配符匹配文件名
标准输出:一般可以配合管道使用
1
2
# 将 a 替换为 my 后显示全部内容。
echo "this is a test string" | sed -e "s/a/my/g"
打印指定行相关内容
指定行打印
sed -n -e "${START_LINE},${END_LINE}p" ${FILE}
获取行号,可以使用grep或awk。
1
2
3
4
5
# 使用awk获取行号,根据匹配的内容获取对应的行号
awk '/match_context/{print NR}' ${FILE}
# 使用grep ,配合-n参数,这个还需要进一步去掉后面的内容,可以使用awk来完成
grep -n "match_context" ${FILE} | awk -F: '{print $1}'
可以打印两个行之间的内容,也可以打印起始行之后n行的内容。
打印具有内容的相关行
打印具有香菇
1
2
3
4
5
6
7
8
9
sed -n "/${MATCH_STR}/p" ${FILE}
# example
$ cat ./st.txt
aaa bbb ccc
111 222 333
last line
$ sed -n "/22/p" ./st.txt
111 222 333
删除内容
删除具体某行 或 a到b行。
1
2
3
4
5
6
7
# 操作原文件
sed -i "${LINENO}d" ${FILE}
sed -i "${START_LINE},${END_LINE}d" ${FILE}
# 预览效果
sed -e "${LINENO}d" ${FILE}
sed -e "${START_LINE},${END_LINE}d" ${FILE}
删除最后一行
1
sed -i '$d' ${FILE}
删除有特定匹配内容的行
如有匹配字符串${MATCH_STR},删除具有该字符串的行:
1
2
3
4
5
# 操作原文件
sed -i "/${MATCH_STR}/d" ${FILE}
# 预览效果
sed -e "/${MATCH_STR}/d" ${FILE}
追加内容
注意:是在匹配的内容所在行的下一行插入新的行,不是直接在后面添加内容
1
sed -e "/pattern/a additional_content" input.txt
example:
1
2
3
$ echo "aa bb cc" | sed -e "/bb/a my new addition"
aa bb cc
my new addition
替换内容
基本用法: s/匹配模式/替换字符串/[标志]
- 匹配模式:是一个正则表达式模式,用于匹配要替换的文本。
- 替换字符串:是替换后的字符串,用于替换匹配到的文本。
- 标志:sed命令支持一些标志,用于修改替换行为。
- g:全局替换标志,表示替换所有匹配到的文本,而不仅仅是第一个匹配项。
- n:禁止默认输出,只打印经过替换后的结果。
- p:打印替换行,并在默认输出之前打印原始行。
测试文本:
1
2
3
4
5
cat ./test.txt
aaa bbb ccc
11223344
abcd
last line
默认每行只替换第一个匹配的项
1
2
3
4
5
6
7
8
9
10
11
$ sed -e "s/a/z/" ./test.txt
zaa bbb ccc
11223344
zbcd
lzst line
$ sed -n -e "s/a/z/p" ./test.txt
zaa bbb ccc
zbcd
lzst line
全部提替
加上g标志即可。
1
2
3
4
5
6
7
8
9
10
11
$ sed -e "s/a/z/g" ./test.txt
zzz bbb ccc
11223344
zbcd
lzst line
$ sed -n -e "s/a/z/pg" ./test.txt
zzz bbb ccc
zbcd
lzst line
限定范围行
在s前加行号即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 仅对第一行替换
$ sed -e "1s/a/z/g" ./test.txt
zzz bbb ccc
11223344
abcd
last line
$ sed -n -e "1s/a/z/pg" ./test.txt
zzz bbb ccc
# 两个行号之间,"1,3"即[1,3]行的行号范围
$ sed -e "1,3s/a/z/g" ./test.txt
zzz bbb ccc
11223344
zbcd
last line
$ sed -n -e "1,3s/a/z/pg" ./test.txt
zzz bbb ccc
zbcd
特殊标记
特殊标记&
该标记表示与模式匹配的内容,可以用来方便的扩展匹配的文本字符串。
1
2
# 将 test 替换为 "test",加上双引号,双引号需要转义
echo "this is a test str" | sed -e "s/test/\"&\"/g"
特殊标记 \#
该标记用于表示 匹配字符串中的子字符串,上面的&
一般只能用来扩展,不能在里面修改,使用\#
或可实现。 \#
中的#
表示子字符串序号,具体指定为1,2,3,4这种,如 具体使用时,需要写为 \1
,\2
,\3
这种。 子字符串使用 ()
包围,(
和)
都需要转义,即实际使用\(substr\)
表示一个子字符串,后面\1
表示第一个 子字符串,\2
表示第二个子字符串,以此类推。
该特殊标记可以操作子字符串,实现更复杂的替换操作,示例:
1
2
3
4
5
6
# 将 "apple is fruit" 替换为 "fruit is not only apple"
echo "as is known,apple is fruit" | sed -e "s/\(apple\) is \(fruit\)/\2 is not only \1/g"
# 还可以配合正则表达式等
echo "Name : John" | sed -e "s/\(Name\) : \(.*\)/\2 : \1/g"
echo "this year was 2020" | sed -e "s/year was \([0-9]*\)/year \1 was very substantial/g"
特殊标记 \<
和\>
用于精确匹配单词。
1
2
3
4
5
6
7
# 将单词 world 替换为 666,注意第一个helloworld是连在一起的,不是一个精确的world单词
echo "helloworld,this is linux world."| sed -e "s/\<world\>/666/g"
helloworld,this is linux 666.
#默认是不区分单词的,直接匹配
echo "helloworld,this is linux world."| sed -e "s/world/666/g"
hello666,this is linux 666.
其他
\n
,\t
分别是换行和制表符,也可以使用。