参考、推荐资料:
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