cat /etc/redhat-release看到操作系统是CentOS Linux release 7.6.1810,uname -r看到内核版本是3.10.0-957.el7.x86_64,bash --version可以看到bash版本是4.2.46(2)。

sed(sed strem editor)可以理解为行编辑器,但它并不直接编辑文本文件本身,其默认对原文件内容不做任何修改。sed在处理文件的时候,每次都会逐行把文件内容读取到内存中,然后使用特定的模式对读入的文件内容进行处理,这样的一段内存空间成为模式空间。
sed的两种处理方法:
把文本全部内容逐行读取到模式空间中,在模式空间中会有指定的模式,然后把读取到的行和模式空间中的模式做匹配.
读取文本时把符合模式条件的内容逐行读取到模式空间中,符合模式过滤条件的,则在模式空间中做相对应的编辑处理,把模式空间中的内容显示输出,不符合的则不做处理并直接按原样输出。
sed格式有两种,如下:
sed [OPTIONS]… ‘COMMAND’ [FILE]…
sed [OPTIONS] -f SCRIPTFILE [FILE]…
sed的替换命令是s,普通格式如下:
sed 's/oldstring/newstring/' filename,这个会把模式空间中匹配的第一个oldstring改成newstring,但是这个不会在原文件filename中操作。
sed -e 's/oldstring1/newstring1/' -e 's/oldstring2/newstring2/' filename,这个会把模式空间中匹配的第一个oldstring1改成newstring1,然后修改过之后的字符串上,把第一次匹配的oldstring2改成newstring2,同样的,这个不会在原文件filename中操作。
sed -i 's/oldstring1/newstring1/' filename,这个会把模式空间中匹配的第一个oldstring1改成newstring1,修改过之后的内容会输出到原文件filename中。
可以使用正则表达式的格式如下:
`sed ‘s/正则表达式/newstring/’ filename
`sed -r ‘s/拓展正则表达式/newstring/’ filename
sed ‘s/oldstring/newstring/’ filename
echo a:aa:aaa >> sedtest.txt
echo a:bb:aa >> sedtest.txt
echo cc : cc : ccc >> sedtest.txt
上边三条命令把下边的内容写到sedtest.txt:
a:aa:aaa
a:bb:aa
cc : cc : ccc

sed 's/a/aa/' sedtest.txt,可以看到每一个的第一个a被替换成了aa,再使用cat sedtest.txt可以看到sedtest.txt里边的内容没有任何改变。

echo 'go/d' >> sedtest.txt把go/d写入到sedtest.txt中,cat sedtest.txt可以看到sedtest.txt中的内容如下:
a:aa:aaa
a:bb:aa
cc : cc : ccc
go/d
若是想要把/改成o,而要使用sed 's///o/' sedtest.txt会报错
sed: -e expression #1, char 5: unknown option to \`s'

有两种方法,第一种使用转义字符sed 's/\//o/' sedtest.txt,cat sedtest.txt可以看到sedtest.txt中的内容没有发生改变。

第二种是更改定界符,可以把定界符改为!,sed 's!/!o!' sedtest.txt,cat sedtest.txt可以看到sedtest.txt中的内容没有发生改变。

定界符也可以改为#、@这些字符,sed 's#/#o#' sedtest.txt,sed 's@/@o@' sedtest.txt。

sed -e选项
echo '::' >> sedtest.txt把::写入到sedtest.txt中,cat sedtest.txt可以看到内容如下:
a:aa:aaa
a:bb:aa
cc : cc : ccc
go/d
::

sed -e 's/aa/z:/' -e 's/::/oo:/' sedtest.txt | cat -n先把aa换成z:,然后在上一步已经替换的基础上再次把::替换成oo:,可以看到第1行中的aa已经被替换成了zoo,第2行中的aa只是被替换成z:,第5行中::改成了oo:,|是管道符,就是把前边的输出当成后边命令的输入标志,cat -n把内容带上行号输出。cat sedtest.txt可以看到sedtest.txt中的内容没有发生改变。

sed 's/aa/z:/;s/::/oo:/' sedtest.txt | cat -n,把两个-e选项去掉,然后把命令之间使用;隔开也可以实现上边的效果。cat -n sedtest.txt可以看到sedtest.txt中的内容没有发生改变。

sed -i选项
sed -i 's/oldstring1/newstring1/' filename,这个会把模式空间中匹配的第一个oldstring1改成newstring1,然后把修改结果写到文件filename中。
cat -n sedtest.txt可以看到如下内容:
1 a:aa:aaa
2 a:bb:aa
3 cc : cc : ccc
4 go/d
5 ::
前边的1、2、3、4和5是行号,不是sedtest.txt里边的内容。
sed -i 's/\//o/' sedtest.txt会把/改成o,然后把更改过之后内容写入到sedtest.txt,cat -n sedtest.txt可以看到更改之后的如下内容:
1 a:aa:aaa
2 a:bb:aa
3 cc : cc : ccc
4 good
5 ::
发现文件中的/改成了o。

sed正则支持
.匹配除换行符之外的任意一个字符,只能匹配一个字符。
sed 's/.:/love:/' sedtest.txt将第一组任意字符+:的字符串替换成love:,cat -n sedtest.txt可以看到sedtest.txt中的内容没有发生改变。

*匹配它之前一个字符或者一个正则表达式0至若干次。
sed 's/c* /c/' sedtest.txt | cat -n,可以看到cc 被替换成了c,cat -n sedtest.txt可以看到sedtest.txt中的内容没有发生改变。

^匹配一行的开始
echo ca:r >> sedtest.txt 把ca:r写到文件sedtest.txt最后一行,cat -n sedtest.txt可以看到更改之后的如下内容:
1 a:aa:aaa
2 a:bb:aa
3 cc : cc : ccc
4 good
5 ::
6 ca:r

sed 's/a:/d:/' sedtest.txt | cat -n会把第六行中的a:改为d:,而sed 's/^a:/d:/' sedtest.txt | cat -n没有更改第六行中的a:。

sed -r 拓展元字符
+匹配它前边字符一次或多次
echo 'a' >> sedfiletest.txt
echo 'aa' >> sedfiletest.txt
echo 'aaa' >> sedfiletest.txt
echo 'ab' >> sedfiletest.txt
echo 'aab' >> sedfiletest.txt
echo 'aaabbb' >> sedfiletest.txt
把下边的内容:
a
aa
aaa
ab
aab
aaabbb
写入到sedfiletest.txt里边。cat sedfiletest.txt看一下sedfiletest.txt里边内容。

sed -r 's/a+b/:/' sedfiletest.txt可以匹配ab、aab、aaab和aaa......b。

echo 'b' >> sedfiletest.txt,把b写入到sedfiletest.txt里边。cat sedfiletest.txt看一下sedfiletest.txt里边内容。

sed -r 's/a?b/:/' sedfiletest.txt,?只能匹配它前边的字符0次或者1次,不会匹配其他次数。

sed -r 's/a|b/:/' sedfiletest.txt | cat -n,|相当于或的意思,就是a或者b的意思,cat -n sedfiletest.txt发现文件里边的内容没有改变。

sed -r 's/(aa)|(b)/:/' sedfiletest.txt | cat -n,()相当于组合的意思,就是aa或者b的意思,cat -n sedfiletest.txt发现文件里边的内容没有改变。

()还可以用于回调,就是可以当成一个变量暂时使用。sed -r 's/(aa)|(b)/\1:\2/g' sedfiletest.txt | cat -n这里的\1相当于aa,\2相当于b。

find / -name passwd
此文章为8月Day 7学习笔记,内容来源于极客时间《Linux 实战技能 100 讲》。



















