sed常用方法与命令

参考、推荐资料:

http://www.grymoire.com/Unix/Sed.html#uh-40 (很全)

http://www.linuxhowtos.org/System/sed_tutorial.htm (内容少、速成)

http://maketecheasier.com/beginners-guide-to-sed-linux/2012/03/29

http://how-to.linuxcareer.com/learning-linux-commands-sed#h3-concepts (有很多例子)

 

sed是stream editor的缩写,不同于vim,它是非交互模式的,一次处理一行内容。

处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。

接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

友情提示:MacOS自带的sed不是GNU标准的,很多语法不兼容但并不报错,换gsed能解决99%的问题!

假设我们的文件如下:

$ cat ./test.txt 
file line 1
file line 2
file line 3
file line 4
file line 5

1、删除行:使用d执行符。

两种语法

# 正则表达式删除
sed '/regex/ d' test.txt

# 行号删除
sed '[first line to delete] [last line to delete] d' test.txt

删除1~3行:

$ cat ./test.txt | sed '1,3d'
file line 4
file line 5

删除2~末尾行:

$ cat ./test.txt | sed '2,$d'
file line 1

删除含有单词"line 3"的行:

$ cat ./test.txt | sed '/line 3/d'
file line 1
file line 2
file line 4
file line 5

删除1~2,第5行:

需要使用两次-e,每一个-e后面接一套sed命令,执行完第一个-e,再执行第二个-e。

$ cat ./test.txt | sed -e '1,2d' -e '5,5d'
file line 3
file line 4

删除多余的行:

sed '/^[ \t]*$/d'

2、只输出改变的行:-n配合执行符号p。

p表示print,即打印。

-n表示静默,即默认不输出,除非sed命令中要求了输出,例如p命令。

如下,类似于grep出含有line 1 的行。

sed -n '/line 1/p'
file line 1

3、插入行:i和a

命令i:在行前插入。

命令a:在行后插入。

在第1行前插入:

$ cat ./test.txt | sed '1i insert line x'
insert line x
file line 1
file line 2
file line 3
file line 4
file line 5

在匹配‘line 3’的行后面插入:

$ cat ./test.txt | sed '/line 3/a\insert line x'
file line 1
file line 2
file line 3
insert line x
file line 4
file line 5

4、取代行(替换行)

将第1行替换为xxx:

$ cat ./test.txt | sed '1c\xxx'
xxx
file line 2
file line 3
file line 4
file line 5

5、正则表达式替换

基本语法

sed -re 's/regex1/regex2/' test.txt

基于行的匹配部分,不再是整个行,要使用s!!

格式为s/regex/replace/...,...可以使用g(全局),p打印等。

对每一行执行一次regex正则匹配,如果匹配了,用replace替换匹配的部分!

假设文件:

cat ./test.txt 
file line line 1
file line 2
file line 3
file line 4
file line 5

替换第一次出现的line为linex:

$ cat ./test.txt | sed 's/line/linex/'
file linex line 1
file linex 2
file linex 3
file linex 4
file linex 5

如上所述,默认只匹配、替换第一次match。

可以使用g,替换全部:

$ cat ./test.txt | sed 's/line/linex/g'
file linex linex 1
file linex 2
file linex 3
file linex 4
file linex 5

可以在replace部分使用&表示匹配的部分:

如下,相当于grep:

$ cat ./test.txt | sed -n 's/line 1/&/p'
file line line 1

对第2~末尾次匹配、执行(不管第一次)

$ cat ./test.txt | sed 's/line/linex/2g'
file line linex 1
file line 2
file line 3
file line 4
file line 5

2014.04.21 Update:

替换最后1次出现,可以用rev命令反转 + sed替换第1次 + rev反转实现

echo "1,2,3,4" | rev | sed 's/,/\t/1' | rev
# Output
1,2,3 4

可以在regex部分使用\1 \2等,替代group:

将两个重复的line,替换为none,注意()也要转义!!

$ cat ./test.txt | sed 's/\(line\) /none/'
file none 1
file line 2
file line 3
file line 4
file line 5

先写到这里,想到其他再写!

6、其他

删除空行

sed -re '/^$/ {N; D}' test.txt

8、只取match的group

echo ",pid:123," | sed -rn "s/.*(pid:[0-9]+).*/\1/p" pid:123

9、只取某一行

sed -n '52p'

10、如何在sed中快速嵌入shell命令

 echo "DATE_REPLACE_ME_hh" | sed -e "s/DATE_REPLACE_ME/$(date '+%Y-%m-%d')/g"

11、sed中如何替换\n

需要一些复杂操作:

cat ./1.txt | sed ":a;N;s/\n/,/g;ta"

11、把用逗号分割的一行切割为多行

echo "1,2,3" | sed 's/,/ /g' | tr " " \\n

Leave a Reply

Your email address will not be published. Required fields are marked *