sed 主要用于对文本文件进行编辑操作,包括对文本内容的查找、替换、删除、插入等,这些操作可以基于指定的模式(pattern)来完成。它可以在不打开文件编辑器的情况下,直接在命令行中对文本文件进行处理,特别适用于对大型文本文件或者需要批量处理文本的场景。
- sed 基本语法
sed [选项] '命令' [输入文件]
如果不指定输入文件,sed 可以从标准输入读取数据。例如,echo "hello" | sed's/hello/hi/',这里通过管道将echo输出的内容传递给 sed 进行处理。
- sed 常用选项
-n:安静模式,默认情况下 sed 会输出所有行,但使用-n选项后,只有经过p(打印)命令或者P(打印匹配模式空间中的第一部分内容)命令处理的行才会输出。
-e:允许多个编辑命令同时执行。例如,sed -e 's/old/one/' -e 's/new/two/' file.txt,它会在file.txt文件中先将old替换为one,再将new替换为two。
-i:直接修改输入文件内容(原地修改)。这个操作是不可逆的,会直接覆盖原文件,所以使用时要谨慎。例如,sed -i's/hello/hi/' file.txt会直接在file.txt中把hello替换为hi。如果想备份原文件,可以使用-i.bak(不同系统可能有细微差别),这样会在修改原文件之前先创建一个名为file.txt.bak的备份文件。
-r:使用扩展正则表达式。默认情况下 sed 使用基本正则表达式,使用-r选项可以启用更方便的扩展正则表达式语法。例如,sed -r's/(hello)+/hi/' file.txt,这里(hello)+是一个扩展正则表达式,表示一个或多个hello。
- sed 命令的构成
sed 命令一般由地址范围和操作命令组成,格式为[地址范围]操作命令[操作参数]。
- 地址范围
行号指定地址范围
单一行号:如1表示第一行,3表示第三行。例如,sed '3s/hello/hi/' file.txt只对file.txt的第三行进行替换操作。
行号范围:用逗号分隔两个行号,如2,5表示从第二行到第五行。例如,sed '2,5s/hello/hi/g' file.txt在file.txt的第二到第五行内将hello全局替换为hi。
起始行到末尾行:如2,$表示从第二行到文件末尾。例如,sed '2,$d' file.txt会删除file.txt中从第二行开始到文件末尾的所有行。
使用模式匹配指定地址范围
匹配特定字符串的行:用/模式/来指定。例如,sed '/hello/s/world/earth/' file.txt会在file.txt中所有包含hello的行中将world替换为earth。
组合模式匹配:可以使用/模式1/,/模式2/来指定一个范围。例如,sed '/start/,/end/d' file.txt会删除file.txt中从包含start的行到包含end的行(包括这两行)的所有内容。
- 操作命令
替换(s)
基本格式:s/旧字符串/新字符串/[替换标志]。例如,sed's/hello/hi/' file.txt将file.txt中每行的第一个hello替换为hi。
替换标志:
g(全局替换):替换每行中所有匹配的旧字符串。例如,sed's/hello/hi/g' file.txt会将file.txt中每行所有的hello都替换为hi。
p(打印替换行):除了进行替换操作外,还会打印出替换后的行。通常与-n选项一起使用。例如,sed -n 's/hello/hi/p' file.txt只会打印出被替换后的行。
w 文件名(写入文件):将替换后的行写入指定的文件中。例如,sed's/hello/hi/w new.txt' file.txt会把file.txt中替换后的行写入new.txt文件。
删除(d)
示例:sed '2d' file.txt删除file.txt的第二行;sed '/^#/d' file.txt删除file.txt中所有以#开头的行(常用于删除配置文件中的注释)。
插入(i)和追加(a)
插入(i):在指定行之前插入新内容。例如,sed '2i new line' file.txt在file.txt的第二行之前插入new line。插入的内容可以是多行,每行之间用\n分隔,如sed '2i new1\nnew2' file.txt。
追加(a):在指定行之后添加新内容。例如,sed '2a new line' file.txt在file.txt的第二行之后添加new line。同样,追加内容也可以是多行,如sed '2a new1\nnew2' file.txt。
打印(p)
示例:sed -n '3p' file.txt只打印file.txt的第三行;sed -n '/pattern/p' file.txt打印file.txt中包含pattern的行。
- sed命令工作中常用的示例
示例 1:修改文件中的特定单词(全局替换)
sed -i's/error/warning/g' log.txt
将log.txt文件中的所有error单词替换为warning,并且直接修改log.txt原文件。
示例 2:删除文件中的空行
sed '/^$/d' data.txt
删除data.txt文件中所有只包含空白字符(如空格、制表符等)或者完全为空的行。这里^$表示行首到行尾没有任何字符,即空行。
示例 3:在文件特定行前后添加内容
sed '3i This is a new line\nbefore the third line' file.txt
在file.txt文件的第三行之前插入两行内容(This is a new line和before the third line)。如果要在第三行之后添加,可使用a命令,如sed '3a This is a new line\nafter the third line' file.txt。
示例 4:根据模式匹配替换内容并打印替换行
sed -n '/key/s/value/new_value/p' config.ini
在config.ini文件中,对于包含key的行,将其中的value替换为new_value,并只打印出替换后的行。这里结合了模式匹配、替换和打印操作,并且使用-n选项控制输出。
示例 5:指定行替换
将file.txt中第 3 行的apple替换为banana。
sed '3s/apple/banana/' file.txt
这里的3指定了行号,只对第 3 行进行替换操作。如果要在第 2 - 5 行进行替换,可以使用sed '2,5s/apple/banana/' file.txt。
示例 6:删除指定行
删除file.txt的第 5 行。
sed '5d' file.txt
d表示删除操作,这里只删除第 5 行。如果要删除第 3 - 7 行,可以使用sed '3,7d' file.txt。
示例 7:删除匹配模式的行
删除file.txt中所有以#开头的注释行。
sed '/^#/d' file.txt
^#表示以#开头的行,符合这个模式的行都会被删除。常用于清理配置文件中的注释。
示例 8:插入和追加操作
在指定行前插入内容
在file.txt的第 3 行之前插入This is a new line。
sed '3i This is a new line' file.txt
i表示插入操作,新内容会插入到指定行之前。如果要插入多行,可以使用sed '3i This is line1\nThis is line2' file.txt,每行之间用\n分隔。
示例 9:在指定行后追加内容
在file.txt的第 3 行之后追加This is another new line。
sed '3a This is another new line' file.txt
a表示追加操作,新内容会添加到指定行之后。同样,追加多行时每行用\n分隔。
示例 10:备份原文件并修改
备份file.txt为file.txt.bak,同时将file.txt中的old替换为new。
sed -i.bak's/old/new/' file.txt
i.bak选项会在修改file.txt之前创建一个名为file.txt.bak的备份文件,然后进行替换操作。
- sed命令工作中常用的正则表达式示例
1. 替换操作中的正则表达式
替换每行中的数字为X
命令:sed 's/\d/X/g' file.txt
说明:\d在扩展正则表达式中表示数字,g表示全局替换。此命令会将file.txt文件每行中的数字都替换为X。如果 sed 不支持扩展正则表达式(未使用-r选项),可以写成sed 's/[0-9]/X/g' file.txt。
将以abc开头的单词替换为def
命令:sed 's/\babc\w*/def/g' file.txt
说明:\b是单词边界,\w*表示零个或多个单词字符(字母、数字、下划线)。该命令会把file.txt中所有以abc开头的单词替换为def。
2. 删除操作中的正则表达式
删除包含error的行
命令:sed '/error/d' file.txt
说明:/error/用于匹配包含error的行,d表示删除。这样file.txt中所有包含error的行都会被删除。
删除空行和只包含空白字符的行
命令:sed '/^[[:space:]]*$/d' file.txt
说明:^表示行首,[[:space:]]表示空白字符类(包括空格、制表符等),*表示零个或多个,$表示行尾。此命令可以删除file.txt中完全为空或者只包含空白字符的行。
3. 选择特定行进行操作(基于正则表达式的地址定位)
对以数字开头的行进行替换操作
命令:sed '/^[0-9]/s/old/new/g' file.txt
说明:^[0 - 9]匹配以数字开头的行,然后在这些行中把old替换为new(全局替换)。
在包含start和end之间的行中追加内容
命令:sed '/start/,/end/a This is new content' file.txt
说明:/start/,/end/用于定位从包含start的行到包含end的行的范围,a表示追加,会在这个范围内的每行后面追加This is new content。
4. 提取特定内容(使用p命令和正则表达式结合)
打印出包含keyword的行
命令:sed -n '/keyword/p' file.txt
说明:-n选项使得 sed 只输出经过p(打印)命令处理的行。这里/keyword/匹配包含keyword的行,然后将这些行打印出来。
提取每行中所有的数字并打印
命令:sed -n 's/\([0-9]\+\)/\1/p' file.txt
说明:\([0 - 9]\+\)是一个分组,用于匹配一个或多个数字,\1表示引用第一个分组(即匹配到的数字)。此命令先进行替换(这里替换为自身),然后打印包含数字的部分,-n选项控制只打印处理后的行。
5. 复杂的正则表达式示例
将file.txt中类似abc123(abc后跟数字)的字符串替换为XYZ
命令:sed 's/abc[0-9]\+/XYZ/g' file.txt
说明:abc[0 - 9]\+表示匹配abc后面跟着一个或多个数字的字符串,然后将其替换为XYZ。
将file.txt中http://或https://开头的网址替换为[URL]
命令:sed 's/(http:\/\/|https:\/\/)[^ ]*/[URL]/g' file.txt
说明:(http:\/\/|https:\/\/)是一个分组,用于匹配http://或者https://,[^ ]*表示匹配除空格以外的任意字符零次或多次(这里用于匹配网址的其余部分)。此命令会把file.txt中所有网址替换为[URL]。如果 sed 不支持这种复杂分组(未使用-r选项),可以分两步进行替换,先将http://开头的替换,再将https://开头的替换。