sed命令:
文本处理三剑客:
grep、egrep、fgrep:文本过滤器;
sed:Stream 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:删除第1到5行;
]# sed -n '1,5d' ]# /etc/fstab:删除第1到5行,同时不显示模式空间中没被匹配的行;
]# 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操作:把保持空间的内容追加至中模块空间中(模式空间有第2、1行,保持空间有第1行),执行h把模式空间中的内容覆盖至保持空间中(保持空间有第2、1行),执行不是最后一行就执行d删除模式空间中的行(模式空间为空);
读取第三行,执行不是第一行,执行G操作(模式空间有第3、2、1行,保存空间有第2、1行),执行h(保持空间有第3、2、1行),执行不是最后一行就执行d(为最后一行即执行d);
sed '$!d' FILE:显示文件的最后一行;
sed '$!N;$!D' FILE:显示文件最后两行;
例如:
]# sed '$!N;$!D' /etc/fstab
读第一行,执行不是最后一行执行N读取匹配到的行的下一行并追加至模式空间中(模式空间为第1、2行),执行不是最后一行,执行D删除多行模式空间中的所有行(模式空间为空);
读第三行,执行不是最后一行执行N(模式空间有第3、4行),执行不是最后一行执行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:原处修改;
注意:任何要修改配置文件的操作,事前要先做好备份;