欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【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] 1234


9.子串匹配

如果想要表示匹配的其中一部分字符串,需要使用\x,x代表匹配的第x个字符串。

例子:

(1)交换输入的两个字符串:

echo hello world | sed 's/\([a-z]\{1,\}\) \([a-z]\{1,\}\)/\2 \1/'
输出就会从hello world变成world hello。这里每个需要匹配的模式都用()包括住了,然后用\2 \1表示输出第二个匹配的字符串 第一个匹配的字符串,即完成了交换。