【shell】sed命令及常见用法
程序员文章站
2022-06-18 20:18:59
...
【背景】
sed全称为stream editor,是linux中很常见的一个文本处理命令。sed主要以行为单位处理文本,实现对输入数据进行增、删、替换等功能。该命令的执行流程是每次读入一行输入,处理数据并将结果打印到屏幕上,然后读入下一行数据并以此循环,输入文件的内容本身并无任何改变。若有需要也可以使用特定选项或者重定向来将结果保存到文件。
【命令格式】
sed命令根据实际的用途而在形式上会稍微有点差异,所以这里不给出统一的格式,而是在下面的实际例子中给出特定用途下的格式。
【常见用法】
1.替换特定字符串
命令形式:
sed 's/pattern/replace_str/[g]' filename
或者
cat filename | sed 's/pattern/replace_str/[g]'
因为sed命令也支持stdin作为输入。
或者
sed 'x[,y]c' filename
这里x,y代表行号,c表示替换命令。
例子:
(1)将输入的第一个me替换成ME:
echo mememe | sed 's/me/ME/'
输出为MEmeme。
(2)将输入的所有me替换成ME:
echo mememe | sed 's/me/ME/g'
输出为MEMEME,注意这里相比第一个例子新增了g,这代表sed会替换每一处匹配。
(3)将第1到2行数据替换为hahaha:
sed '1,2c hahaha' filename
2.删除特定行
命令形式:
sed 'x[,y]d' filename
这里x,y表示行号,d为删除命令
或者
sed '/pattern/d' filename
这里使用模式来匹配行,并将匹配成功的行删除掉例子:
(1)删除文件test的第二行:
sed '2d' test
(2)删除文件test的第二到第三行:
sed '2,3d' test
另外,可以用$表示最后一行。
(3)删除空白行:
sed '/^$/d' filename
3.新增行
命令形式:
sed 'xa string'
x表示行号,a表示将string增加到x行的下一行
或者
sed 'xi string'
x表示行号,i表示将string增加到x行的上一行
例子:
(1)增加hello到第二行的下一行:
sed '2a hello' filename
4.打印特定行
命令形式:
sed -n 'x[,y]p' filename
x,y表示行号,p表示打印命令
或者
sed -n '/pattern/p' filename
这里使用模式匹配,能够和pattern匹配的行会被输出
注意需要使用-n选项(安静模式),否则特定/匹配成功的行会被打印两遍。
5.将输出保存到文件
sed的输出是打印到屏幕的,如果想输出到文件则需要额外操作。
(1)重定向:
sed 's/string/str/g' filename > newfile
确认newfile的内容无误后再替换掉filename即可。不过这样有点麻烦,还可以用下面的选项简化操作。
(2)使用-i选项
sed -i 's/string/str/g' filename
使用-i选项将结果保存到输入的文件中
(3)创建临时文件的方法
sed -i.tmp 's/string/str/g' filename
直接使用-i选项会覆盖输入文件,万一命令有误就会导致原有文件的内容被破坏,一个比较稳妥的办法是在-i选项后面增加文件后缀,这样会创建filename.tmp并将输出保存在该文件中,而原有文件不会被修改。
6.使用其他定界符
/字符是常见的sed定界符,但是也可以使用:、|作为定界符。
sed 's:string:str:' filename
sed 's|stirng|str|' filename
7.使用双引号
sed一般使用单引号,但是也可以使用双引号,此时会对变量进行求值。
text=hello
echo hello world | sed "s/$text/HELLO/"
输出为HELLO world
8.字符串匹配
&在sed中表示已经匹配的字符串,可用于一些特定场景。
例子:
(1)将输入的单词使用括号包围:
echo haha 1234 | sed 's/[a-zA-Z]\{1,\}/[&]/g'
该命令表示将单词周围加上方括号,其输出为[haha] 12349.子串匹配
如果想要表示匹配的其中一部分字符串,需要使用\x,x代表匹配的第x个字符串。
例子:
(1)交换输入的两个字符串:
echo hello world | sed 's/\([a-z]\{1,\}\) \([a-z]\{1,\}\)/\2 \1/'
输出就会从hello world变成world hello。这里每个需要匹配的模式都用()包括住了,然后用\2 \1表示输出第二个匹配的字符串 第一个匹配的字符串,即完成了交换。