一起学习sed(一)

mp.weixin.qq.com/s/oTqE (2018-12-31)


Unix中的两大文本编辑处理神器 - awk sed 。之前我们已经介绍过了 awk

那么今天学习一些sed. sed是 stream editor 的简称。sed可以在命令行通过简单的命令操作,完成十分复杂的任务,是十分强大有用的工具。

在学习sed之前,我们先建立一个如下的文本文件,以便后续练习:example.txt

This is a test file.
It is the last day of 2018.
Hope all you success!
HAPPY NEW YEAR!


基本用法:

sed "s/正则表达式(或要替换的具体字符)/目标字符/flag" 操作文件

如果你了解sed,那么想必你最熟悉的应用就是使用s进行文本替换了。比如将example.txt中的2018替换成2019.

$ sed "s/2018/2019/" example.txt
This is a test file.
It is the last day of 2019.
Hope all you success!
HAPPY NEW YEAR!

如果你想把 exmaple.txt 中的is替换成was:

$ sed "s/is/was/" example.txt
Thwasis a test file.
Itwasthe last day of 2018.
Hope all you success!
HAPPY NEW YEAR!

非常奇怪的是第二行的is被替换成了was,而第一行的is没有被替换,但是“this”被替换成了“thwas“,这是因为在上述命令行中, sed只默认替换每一行的第一个“is”


用`&`表示要替换的字符

如在example.txt中,要把所有的数字加上括号

$ sed "s/[0-9]/(&)/g" example.txt
This is a test file.
It is the last day of(2)(0)(1)(8).
Hope all you success!
HAPPY NEW YEAR!

其中[0-9]只正则表达式,表示数字0-9,而&则表示你前面要替换的内容,你不知道具体是哪一个数字,所以可以用 & 来代替, g 表示 global ,即不仅仅是将每行符合条件的第一处做替换,而是将所有符合条件的字符都进行替换。再如,将每一个单词的首字母变成大写字母:

$ sed "s/ [a-z]/\U&/g" example.txt 
This Is A Test File.
It Is The Last Day Of 2018.
Hope All You Success!
HAPPY NEW YEAR

其中, \U 表示将匹配项变成大写字母( \L 表示变为小写字母) ,而 & 表示保留变换之后的模式。


\1 \2 表示匹配项

\1 表示正则表达式中第一个括号里面的内容。如在example.txt中,要把所有的数字加上括号,前面我们使用&符号完成的,下面还可以用 \1 来完成这个任务

$ sed "s/\([0-9]\)/(\1)/g" example.txt
This is a test file.
It is the last day of (2)(0)(1)(8).
Hope all you success!
HAPPY NEW YEAR!

注意正则表达式一定要用括号括起来,而且括号要有反义字符“\” 再如,我们要把每一行第一个小写字母之后的所有内容删除。

$ sed "s/\([a-z]\).*/\1/" example.txt 
HAPPY NEW YEAR!

再来复杂一点的,将每一行第一个单词的首位字母互换位置:

$ sed "s/\(.\)\(\S*\)\(.\) /\3\2\1 /" example.txt
shiT is a test file.
tI is the last day of 2018.
eopH all you success!
YAPPH NEW YEAR!


其中 \S 表示非空格字符 。这儿重要的记住一点:在正则表达式中用括号括起来的内容,可以依次用\1,\2,\3…(最高到9)的形式在目标字符串中引用。


FLAG区域:1、2表示第几处

前面提到, sed "s/[0-9]/(&)/g" example.txt 中g的作用是告诉sed要替换全部,不仅仅是每一行第一个符合条件的。那么如果是你想替换的是仅仅是第二个满足条件的呢?

那么可以在flag区域使用数字表示第几个满足条件的。如

$ sed 's/[0-9]/(&)/2' example.txt
This is a test file.
It is the last day of 2(0)18.
Hope all you success!
HAPPY NEW YEAR!

这里的2表示将每一行的第二个数字用括号括起来。



FLAG区域: /p 表示输出被修改的行

sed的参数 -n表示不输出结果

$ sed -n  's/[0-9]/(&)/2' example.txt
# 没有输出结果

如果我们在flag区域加上p,就能够之输出我们做过修改的行,其他行不会输出。所以-n和p经常联合使用

$ sed -n 's/[0-9]/(&)/2p' example.txt
It is the last day of 2(0)18.



FLAG区域: /w 将结果输出

使用格式为 /w 文件名 ,如下将结果输出到tt.txt文件中:

$ sed 's/[0-9]/(&)/w tt.txt' example.txt
This is a test file.
It is the last day of (2)018.
Hope all you success!
HAPPY NEW YEAR!
$ cat tt.txt