sed命令:

文本处理三剑客:

grepegrepfgrep:文本过滤器;

sedStream EDitor,流编辑器,行编辑器;

awk:文本格式化工具,报告生成器;

 

sed工作原理:

将文本中一次读取一行,并且复制一份到sed自己的工作区域,这个工作区域叫作模式空间(pattern space),在模式空间进行文本处理以后,将结果送到标准输出;默认sed对文本的每一行做处理操作,也可以定义sed仅处理符合条件(基于正则表达式来进行文本过滤)的行;(默认不对原文件进行编辑);

 

所以在模式空间中读取一行后,首先判断是否符合sed所指定的模式,如果符合则进行定义的编辑操作,将结果输出到标准输出,如果不匹配则默认输出到标准输出(默认是输出操作),也可以定义不输出没被sed模式匹配到的行;然后读取第二行,以此类推;

 

sed内部不仅有模式空间,还有一个空间叫holdspace保持空间,可以将被sed模式匹配到的行编辑完以后存放到保持空间里(高级用法);

 

sed [OPTION]... 'script' [input-file]...

script

地址定界编辑命令

 

常用选项:

-n:不输出模式空间中的内容至屏幕;

-e script, --expression=script:实现多点编辑;

例如:

]# sed -e 's@^#[[:space:]]*@@' -e'/^UUID/d' /etc/fstab

 

-f /PATH/TO/SED_SCRIPT_FILE:每行一个sed编辑命令,保存一个文件,读取文件来进行编辑操作;

-r, --regexp-extended:支持使用扩展正则表达式;

-i[SUFFIX], --in-place[=SUFFIX]:直接编辑原文件;

 

地址定界:(类似vim中末行操作)

1)不给地址:表示对全文进行处理;

2)单地址:

#:指定第#

/pattern/:被此模式所匹配到的每一行;

3)地址范围

##:从第#行开始到第#行结束;

#+#:从第#行开始,加#行;

#/pat1/:从第#行开始,到第一次被模式匹配的行结束;

/pat1/,/pat2/:从被模式1匹配到的第一行开始,到被模式2匹配到的第一行结束;

$:最后一行;

4)不进:~

1~2:表示从1开始,步进2行,如3,5,7行即所有奇数行;

2~2:表示所有偶数行;

 

sed常用编辑命令:

d:删除模式空间内容;

例如:

]# sed '1,5d' /etc/fstab:删除第15行;

]# sed -n '1,5d' ]# /etc/fstab:删除第15行,同时不显示模式空间中没被匹配的行;

]# sed '3d' /etc/fstab:删除第3行;

]# sed '/^UUID/d' /etc/fstab:删除以UUID开头的行;

]# sed '1~2d' /etc/fstab:显示偶数行,即删除奇数行;

p:显示模式空间中内容;(根据地址定界和编辑命令后显示)

例如:

]# sed '1~2p' /etc/fstab:显示2遍所有奇数行,即偶数行没被匹配显示一遍,又显示一遍匹配到的奇数行;

]# sed -n '1~2p' /etc/fstab:显示一遍所有奇数行,即不显示没被匹配的行;

]# sed '1~2d' /etc/fstab:显示偶数行,即删除奇数行;

a \test:在匹配到的行后面追加文本"test",支持使用\n实现多行追加;

i \test:在匹配到的行前面插入文本"test",支持使用\n实现多行插入;

例如:

]# sed '3i \new line' /etc/fstab:在第三行上面插入一行newline

]# sed '3a \new line' /etc/fstab:在第三行下面插入一行newline

]# sed '3a \new line\nanother new line'/etc/fstab:在第三行下面插入2行;

]# sed '/^UUID/a \# add new device base onUUID' /etc/fstab:在UUID开头的行下面添加一行# add new device base on UUID

c \test:把匹配到的行替换为此处指定的文本"test"

例如:

]# sed '/^UUID/c \# add new device base onUUID' /etc/fstab:把UUID开头的行替换为# add new device base on UUID

w /PATH/TO/SOMEFILE:保存模式空间中匹配到的行至指定的文件中;

例如:

]# sed -n '/^[^#]/p' /etc/fstab:显示非#开头的行;

]# sed -n '/^[^#]/w /tmp/fstab.bak'/etc/fstab:把非#开头的行保存至/tmp/fstab.bak文件里;

]# cat /tmp/fstab.bak:验证保存结果;

r /PATH/TO/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面,实现文件合并;

例如:

]# sed '3r /etc/issue' /etc/fstab:把issue文件,写在fstab文件第3行的后面(文件合并);

]# sed '/^UUID/r /etc/issue' /etc/fstab:把issue文件,写在fstab文件中以UUID开头的行后面;

=:为模式匹配到的行打印行号;

例如:

]# sed '/^UUID/='  /etc/fstab:把UUID开头的行上面加一行号;

!:条件取反;

地址定界!编辑命令;

例如:

]# sed '/^[^#]/d' /etc/fstab:删除非#开头的行;

]# sed '/^#/!d' /etc/fstab:删除非#开头的行;

]# ! sed '/^#/d' /etc/fstab:删除非#开头的行;

s///:查找替换,其分隔符可自行指定,常用有s@@@s###等;

替换标记:

g:全局替换;

w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中;

p:仅显示替换成功的行;

 

练习:

1、删除/etc/grub2.cfg文件中所有以空白字符开头的行的行首的所有空白字符;

]# sed 's@^[[:space:]]\+@@' /etc/grub2.cfg

 

2、删除/etc/fstab文件中所有以#开头的行的行首的#号及#后面的所有空白字符,删除以UUID开头的行;

]# sed -e 's@^#[[:space:]]*@@' -e'/^UUID/d' /etc/fstab

 

3、输出一个绝对路径给sed命令,取出器目录,其行为类似于dirname

]# echo "/var/log/messages" | sed's@[^/]\+/\?$@@'

]# echo "/var/log/messages" | sed's@[^/]+/?$@@' :使用扩展正则表达式;

 

高级编辑命令:

h:把模式空间中的内容覆盖至保持空间中;

H:把模块空间中的内容追加至保持空间中;

g:把保持空间中的内容覆盖至模式空间中;

G:把保持空间的内容追加至中模块空间中;

x:把模式空间中的内容与保持空间中的内容互换;

n:读取匹配到的行的下一行覆盖至模式空间中;

N:读取匹配到的行的下一行并追加至模式空间中;

d:删除模式空间中的行;

D:删除多行模式空间中的所有行(对于N的操作);

 

使用分号,分隔多个命令;

 

常用示例:

sed -n 'n;p' FILE:显示文件的偶数行;

 

例如:为了查看清楚使用cat -n命令;

]# cat -n /etc/fstab

]# sed -n 'n;p' /etc/fstab

显示偶数行,-n表示不显示没被匹配到的行,开始读取第一行时,执行n命令为读取下一行覆盖至模式空间中,就是第二行在模式空间中,又执行了p命令,显示模式空间中的内容;

再循环命令,然后开始读取下一行(读取的是第三行),又执行以上命令,即执行n读取下一行(就是第四行),并执行p显示模式空间中的内容,以此类推,结果显示的为2,4,6...偶数的行;

 

sed '1!G;h;$!d' FILE:逆序显示文件的行;

 

例如:

]# sed '1!G;h;$!d' /etc/fstab

读取第一行,执行不是第一行,执行G操作(是第一行不执行G),执行h把模式空间中的内容覆盖至保持空间中(模式空间和保持空间中都保存了第一行),不是最后一行就执行d删除模式空间中的行(模式空间为空);

读取第二行,执行不是第一行,执行G操作:把保持空间的内容追加至中模块空间中(模式空间有第21行,保持空间有第1行),执行h把模式空间中的内容覆盖至保持空间中(保持空间有第21行),执行不是最后一行就执行d删除模式空间中的行(模式空间为空);

读取第三行,执行不是第一行,执行G操作(模式空间有第321行,保存空间有第21行),执行h(保持空间有第321行),执行不是最后一行就执行d(为最后一行即执行d);

 

sed '$!d' FILE:显示文件的最后一行;

sed '$!N;$!D' FILE:显示文件最后两行;

 

例如:

]# sed '$!N;$!D' /etc/fstab

读第一行,执行不是最后一行执行N读取匹配到的行的下一行并追加至模式空间中(模式空间为第12行),执行不是最后一行,执行D删除多行模式空间中的所有行(模式空间为空);

读第三行,执行不是最后一行执行N(模式空间有第34行),执行不是最后一行执行D(模式空间为空);

读取倒数第2行时,执行不是最后一行执行N(模式空间有最后2行),执行不是最后一行执行D(此时最后一行已经读取完了,即不执行D);结果模式空间中仅保存了最后两行;

 

sed '/^$/d;G' FILE:删除原有的所有空白行,然后为所有非空白行后添加一个空白行;

 

例如:

]# sed '/^$/d;G' /etc/fstab

读取第一行,执行是空白行就是执行d删除,执行G把保持空间的内容追加至中模块空间中(统一添加空白行至非空白行后面);

 

sed 'n;d' FILE:显示奇数行;

 

例如:

]# sed 'n;d' /etc/fstab

读取第一行,执行n读取匹配到的行的下一行覆盖至模式空间中(即用第2行覆盖模式空间中第1行),执行d删除模式空间中的行;默认显示不匹配到的行,结果显示的都是奇数行;

 

sed 'G' FILE:在原有的每一行后面添加一个空白行;

 

例如:

]# sed 'G' /etc/issue

]# sed -i '/^UUID/d' fstab:原处修改;

 

注意:任何要修改配置文件的操作,事前要先做好备份;