概述:
本篇我们主要学习两个功能非常强大的文本编辑器,了解这两种文本编辑器的各自的特点
一、sed命令:
1、sed简介:
sed(Stream EDitor)是一种流编辑器、行编辑器。逐行处理文本内容,即一次处理一行内容,处理时,当前处理的行存储在“模式空间”(pattern space)中,接着用sed命令模式空间中的内容,处理完毕后,把模式空间中的内容送到标准输出;然后处理下一行,重复完成相同的操作直至文件末尾。
sed处理文件时,不会对原文件的内容进行修改,除非用选项-i直接编辑原文件或重定向至原文件存储处理后的结果。
sed主要用来帮助用户自动编辑一个或数个文件,并简化对文件反复操作过程。所以sed是一种非交互式的文本编辑工具(通过用户给定的条件自动逐行处理对应文件)。
2、sed的使用:
使用格式
sed [OPTION]… {script-only-if-no-other-script} [input-file]…
简化理解为:sed [OPTION]…{script} [input-file]… 常用选项(OPTION):
-n:不输出模式空间的内容至屏幕
-e:script,–expression=script:多点编辑
eg:
sed -e "s@^#[[:spcae:]]*@@" -e "/^UUID/d" /etc/fstab
-f /PATH/TO/SED_SCRIPT_FILE 每行一个编辑命令的sed脚本
-r:–regexp-extended:支持使用扩展正则表达式
-i[SUFFIX],–in-place[=SUFFIX]:直接编辑原文件
注意:-i.后缀名 可以先备份文件,然后在原文件处编辑
script:地址定界编辑命令,有两部分组成,彼此之间相邻,不分割
地址定界:指定编辑范围
(1)不给地址-空地址:对全文进行处理
eg:
sed 's/^UUID/UID/' /etc/fstab
(2)单地址:
#:指定行 数字
eg:
sed '2d' /etc/fstab #删除第二行(原文件没变)
/pattern/:被此模式所匹配的每一行
eg:
sed '/UUID/d' /etc/fstab #删除存在UUID的行
(3)地址范围 (#为数字)
#,#:从第#行到第#行的所有行
#,+#:从第#行开始以及之后#行的所有行
eg : 3,+8 包括第3行以及第3行后面8行
#,/pat1/:从第#行到第一次匹配到/pat1/的行的所有行
/pat1/,/pat2/:从第一次匹配到/pat1/的行到第一次匹配到/pat2/的行
eg:
sed -n '/Created/,/Accessible/p' /etc/fstab
注意:如果sed匹配地址定界时能匹配到/pat1/,匹配不到/pat2/,则会从匹配到/pat1/的行开始一直到文尾;如果匹配不到/pat1/,则即使存在/pat2/,也不会匹配到对应的行
(4)步进:~ 隔几行
1~2:奇数行:1、3、5、7、…
2~2:偶数行:2、4、6、8、…
3~5:3、8、13、18、….
编辑命令:确定编辑方式
d:删除匹配的模式空间中的行
eg:
sed '2d' /etc/fstab #删除第二行(原文件没变)
p:显示匹配的模式空间中的内容
eg:
sed -n '/Created/,/Accessible/p' /etc/fstab
a \text:在行后面追加文本"text",支持使用\n实现多行追加
eg:
sed '/UUID/a \aabbcc' /etc/fstab #在全文匹配到UUID的行后追加aabbcc这一行
i \text:在行前面插入文本"text",支持使用\n实现多行插入
sed '/UUID/i \aabbcc' /etc/fstab #在全文匹配到UUID的行前追加aabbcc这一行
c \text:用text替换匹配到的行
sed '/UUID/c \aabbcc' /etc/fstab #在全文匹配到UUID的行替换为aabbcc这一行
w /PATH/TO/SOMEFILE:保存模式空间匹配到的行至指定的文件中;
eg:
sed '2w /tmp/test' /etc/fstab #将/etc/fstab的第2行保存至/tmp/test中
r /PATH/TO/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并
sed '2r /tmp/test' /etc/fstab #将/tmp/test的内容读取追加至/etc/fstab第2行之后
=:为模式匹配到的行打印行号
sed '=' /etc/fstab #给所有行匹配行号
sed '/UUID/=' /etc/fstab #给匹配到的行加行号
注意:行号是按文件中原本行号显示的
!:条件取反(放在地址定界后其他编辑命令前,否则报错)
sed '/UUID/!=' /etc/fstab #给有UUID行意外的行加行号
s///:查找替换,其分隔符可自行制定,常用的有s@@@,s###等;
替换标记:
g:全局替换
我们在使用此编辑命令时,其实只是匹配到这一行的第一次匹配到的内容,这一行之后的内容就不会进行操作了,而g的作用就是这一行的所有能够满足匹配的内容
i:不区分大小写
p:显示替换成功的行
就是操作成功的行会显示一遍,一般和-n搭配
w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中
练习1:删除/boot/grub/grub2.cfg文件中的所有以空白字符开头的行的行首的所有空白字符;
sed "s@^[[:space:]]\+@@" /boot/grub/grub2.cfg
练习2:删除/etc/fstab文件中所有以#开头的行的行首的#号及#后面的所有空白字符;
sed "s@^#[[:spcae:]]*@@" /etc/fstab
练习3:输出一个绝对路径给sed命令,取出其目录,其行为类似于dirname;
echo "/etc/passwd" | sed "s@[^/]\+/\?$@@"
sed命令除了“模式空间”(pattern space),还有一个“hold space”的内存空间,叫保存空间。
sed工作机制是每次读取一行文本至“模式空间”中,在模式空间中完成处理,并将处理后的结果输出至标准输出设备;但是有的时候我们处理完一行后,开始处理另一行,对处理过的行可能还有其他操作,因此sed还有一个“保存空间”,先把处理过的行放到保存空间中,然后后续的处理中再拿回到模式空间中进行处理。
模式空间就好像加工车间而保存空间就相当于“半成品仓库”。
sed的高级编辑命令就是运用于保存空间的
高级编辑命令:
h:把模式空间中的内容覆盖至保持空间中;(模式空间复制一份覆盖保持空间)
H:把模式空间中的内容追加至保持空间中;(模式空间复制一份追加至保持空间内容的后面)
g:把保持空间中的内容覆盖至模式空间中;
G:把保持空间中的内容追加至模式空间中;
x:把模式空间中的内容与保持空间中的内容互换;
n:读取匹配到的行的下一行至模式空间中;并覆盖匹配到的行
N:读取匹配到的行的下一行至模式空间中;并追加匹配到的行后面.
d:删除模式空间中的行
D:删除多行模式空间中的所有行;
示例:
sed -n 'n;p' FILE :显示偶数行
sed '1!G;h;$!d' FILE :逆序行显示文件内容
sed '$!d' FILE :取出最后一行
sed '$!N;$!D' FILE:取出最后两行
sed '/^$/d;G' FILE:删除原有的所有空白行,而后为所有的非空白行后添加一个空白行;
sed 'G' FILE :在原有的每行后方添加一个空白行
是不是有点晕?
为了帮助大家更好的理解sed工作机制,我重申一下以下内容
注意:sed是流编辑器、行编辑器;是逐行处理文件内容的,处理完一行才会处理下一行,最后处理完,并显示结果;
那如何判断这一行处理完成了那?
简单的说就是开始第一次读取处理A行的下一行B行时,就算A行处理完毕了,此时A行处理完毕如果还存在,则显示,不存在则不显示;sed工具对文件中的每行都只是逐行读取处理一次!而保存空间中的内容是读取处理完的内容复制保留下来的,不是重新从文件中读取的。
通过以下示例我们逐一分析理解就可以明白sed命令的运行机制了
示例讲解:
sed 'n;d' FILE;显示奇数行文件内容
1、首先sed工具从FILE文件中提取第一行内容至模拟空间进行处理
n命令是读取匹配到的行的下一行至模式空间中;并覆盖匹配到的行
2、所以准备开始读取处理第二行至模式空间(注意因为开始读取第二行了,也就意味着第一行处理完毕,而此时n命令并没有执行完成,就不能执行后续的d命令了,所以第一行的内容在处理完之后是没有被后续的第二行覆盖的,而没有被d删除,所以会在模式空间中显示出来)
3、第二行内容进入模式空间覆盖掉第一行内容,n命令才算结束,然后才可以开始执行d命令,也就是删除此时模式空间中的第二行内容,此时模式空间中什么也没有自然也不会显示被删除的第二行。
注意:sed命令只会逐行读取处理行一次,因为第一行与第二行都已经读取处理过一次了,所以下次会从第三行开始
4、以此类推,开始读取第三行至模式空间…..
5、直至文件内容末尾
以上纯为个人理解,并不是根据源代码得出的结论,仅希望帮助大家理解sed工作机制
二、vi(vim)文本编辑器
vi:Visual Interface,是一中文本编辑器,所谓文本数据是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码等等
vim是全屏编辑器,编辑空间占据整个屏幕,类似的还有nano,与上文的sed行编辑器不一样。
VIM及Vi IMproved:vi的增强版,vim是模式化的编辑。
vim是交互式编辑器同样与sed编辑器有着不同
vim:模式化的编辑器
工作模式:
编辑模式:命令模式
输入模式
末行模式:内置的命令行接口
打开文件:
vim [options] [file ..]
vim [options] –
vim [options] -t tag
vim [options] -q [errorfile]
+#:打开文件后,直接让光标处于第#行的行首
+/PATT:打开文件后,直接让光标处于第一个被PATTERN匹配到的行的行首
+:打开文件后,直接让光标处于尾行行首
模式转换:
编辑模式:默认模式
编辑模式–>输出模式:
i:isert,在光标所在处输入;
a:appeng,在光标所在处后方输入;
o:在光标所在处下方打开的一个新行;
I:在光标所在行的行首输入;
A:在光标所在行的行尾输入;
O:在光标所在处上方打开的一个新行;
输入模式–>编辑模式
ESC(可以两次)
编辑模式–>末行模式
:
末行模式–>编辑模式
ESC(可以两次)
关闭文件
编辑模式:
ZZ:保存并退出
ZQ:不保存退出
末行模式:
:q 退出
:q!强制提出,不保存此前的编辑操作
:wq保存并推出
:w,:q
:x 保存并退出
:w /PATH/TO/SOMEFILE 另存为
光标跳转:
字符间跳转:
k:上
h:左 l:右
j:下
#COMMAND:跳转由#指定的个数的字符
单词间跳转
w:下一个单词的词首
e:当前或后面一个单词的词尾
b:当前或前一个单词的词首
#COMMAND :跳转由#指定的个数的单词
行首行尾跳转
^:跳转至行首的第一个非空白字符
0:跳转至行首(绝对行首但是不包括tab符)
$:跳转至行尾(绝对行尾即使有空白字符)
行间跳转
#G:跳转至由#指定的行
1G,gg:第一行
G:最后一行
句间跳转
):后一句
(:前一句
#):后几句
…
段间跳转
{:前一段
}:后一段
翻屏:
Ctrl+f:向文件尾部翻一屏
Ctrl+b:向文件首部翻一屏
Ctrl+d:向文件尾部翻半屏
Ctrl+u:向文件首部翻半屏
Enter:向文件尾部翻一行
锁定和解锁:CTRL+s,Ctrl+q
当前页跳转:
H :页首 M行 :页中间行 L: 页底
vim的编辑命令
字符编辑:
x:删除光标所在处的字符
#x:删除光标所在处起始的#个字符
xp:交换光标所在处的字符与其后面的字符的位置
~:转换光标所在处的字符大小写eg: a-A B-b
替换命令(replace):
r(后面跟要换的字符):替换光标所在处的字符;
删除命令:
d:删除命令,科技和光标跳转字符,实现范围删除
d$:删除当前光标处到行尾的内容
d^:删除当前光标处到行首的内容
以下支持#COMMAND
dw:删除当前光标处到下一个单词的词首的内容
#dw删除当前光标处到下#个单词的词首的内容
de:删除当前光标处到当前或后面一个单词的词尾的内容
#de删除当前光标处到当前或后面#个单词的词尾的内容
db:删除当前光标处到当前或前一个单词的词首的内容
#db删除当前光标处到当前或前#个单词的词首的内容
dd:删除光标所在处的行;
#dd:删除光标所处的行起始的共#行
D: : 从当前光标位置一直删除到行尾,留空行,等同于d$
粘贴命令:(p,put,paste)
p:缓冲区中的内容如果为整行,则粘贴在当前光标所在行的下方;否则,则粘贴至当前光标所在处的后方;
P:缓冲区中的内容如果为整行,则粘贴在当前光标所在行的上方;否则,则粘贴至当前光标所在处的前方;
复制命令(yank,y):
y:复制,工作行为类似于d命令
y$:复制当前光标处到行尾的内容
y^:复制当前光标处到行首的内容
y0:复制当前光标处到绝对行首的内容
以下支持#COMMAND
ye:复制当前光标处到当前或后面一个单词的词尾的内容
#ye复制当前光标处到当前或后面#个单词的词尾的内容
yw:复制当前光标处到下一个单词的词首的内容
#yw复制当前光标处到下#个单词的词首的内容
yb:复制当前光标处到当前或前一个单词的词首的内容
#yb复制当前光标处到当前或前#个单词的词首的内容
yy:复制光标所在处的一整行
#yy:复制光标所处的行起始的共#行
Y:复制整行
改变命令(change,c):
编辑模式–>输入模式,实现删除操作;并可以进行输入模式
c$:改变当前光标处到行尾的内容
c^:改变当前光标处到行首的内容
c0:改变当前光标处到绝对行首的内容
以下支持#COMMAND
ce:改变当前光标处到当前或后面一个单词的词尾的内容
#ye改变当前光标处到当前或后面#个单词的词尾的内容
cw:改变当前光标处到下一个单词的词首的内容
#yw改变当前光标处到下#个单词的词首的内容
cb:改变当前光标处到当前或前一个单词的词首的内容
#cb改变当前光标处到当前或前#个单词的词首的内容
cc:改变光标所在处的一整行
#cc:改变光标所处的行起始的共#行
C:删除当前光标到行尾,并切换成插入模式可修改内容
100i字符串 [ESC] 粘贴“字符串 ”100次
<start position><command><end position>
Command:
y 复制、d 删除、gU 变大写、gu 变小写
可视化模式:(类似鼠标)
v:按字符选定
V:按行选定
ctrl-v 按块选定
组合编辑命令:d删除,c删除并修改,y复制
撤销(undo)操作:
u:撤销此前的操作(保存最近50次的操作)
#u:撤销此前#次操作
U:撤消光标落在这行后所有此行的更改
撤销此前的撤销操作:
Ctrl+r
重复执行前一个编辑操作:.
重复前一个操作n次: n.
vim自带的练习教程:vimtutor
vim末行模式(扩展命令模式):Shift+;=:
内建的命令行接口
(1)地址定界 :start_pos[,end_pos]
.:当前行
$:最后一行
#:特定的第#行,例如5即第5行;
#,#:指定行范围,左侧为起始行,右侧为结束行;
#,+#:指定行范围,左侧为起始行绝对编号,右侧为相对于左侧行号的偏移量;例如:3,+7
.,$-1:当前行到倒数第二行
1,$:第一行到最后一行
%:全文
/pattern/:从光标所在处起始向文件尾部第一次被模式所匹配到的行
/pattern1/,/pattern2/:从光标所在处起始,第一次由pat1匹配到的行开始,至第一次由pat2匹配到的行结束之间的所有行
可同编辑命令一同使用,实现编辑操作:
d删除、y复制、c改变,直接跟在地址定界后,不分割
w /PATH/TO/SOMFILE:将选定的范围内的内容保存至某文件中
r /PATH/FROM/SOMEFILE:将指定的文件中的内容读取到指定位置
(2)查找
/PATTERN:从当前光标所在处向文件尾部查找能够被当前模式匹配到的所有字符串;
?PATTERN:从当前光标所在处向文件首部查找能够被当前模式匹配到的所有字符串;
n:下一个,与命令方向相同
N:上一个,与命令方向相反
(3)查找并替换
s:末行模式的命令;使用格式;
s/要查找的内容/替换的内容/修饰符
要查找的内容:可使用正则表达式;但不能使用正则表达式中的元字符
替换内容:不能使用正则表达式,但是可以引用;
如果“查找的内容”部分在模式中使用分组符号在“替换的内容”中使用后向引用
直接引用查找模式匹配到的全部文本,要使用&符号
修饰符:
i:查找时忽略大小写
g:全局替换,意味着一行中如果匹配到多次,则均被替换
gc:全局替换,每次替换前询问
%s/This/this/gi
可把分割符替换为其他非常用的字符:
s@@@
s###
(4)命令使用
!command 执行命令
r!command 读入命令的输出
以二进制方式打开文件
vim –b binaryfile
扩展命令模式下,利用xxd 命令转换为可读的十六进制
:%!xxd
编辑二进制文件
扩展命令模式下,利用xxd 命令转换回二进制
:%!xxd –r
保存并退出
示例:
%s@\<t\([[:alpha:]]\+\)\>@T\1@g
%s@\<t[[:alpha:]]\+\>@&er@g
练习:Centos7版本
1、复制/etc/grub2.cfg文件至/tmp目录中,用查找替换命令删除/tmp/grub2.cfg文件中以空白字符开头的行的行首的空白字符;
%s@^[[:space:]]\+@@g
2、复制/etc/rc.d/init.d/functions文件至/tmp目录中,用查找替换命令为/tmp/functions文件的每个以空白字符开头的行首加上#;
%s@^[[:space:]]\+[^[:space:]]@#&@g
3、为/tmp/grub2.cfg文件的前三行的行首加上#号
1,3s@^[[:space:]]\+[^[:space:]]@#&@g
4、将/etc/yum.repos.d/CentOS-Base.repo文件中所有的enabled=0替换为enabled=1,所有gpgcheck=0替换为gpgcheck=1;
%s@\(enabled\|gpgcheck\)=0@\1=1@g
vim多文件功能
多文件(一次打开多个文件)
vim FILE1 FILE2 …
文件间切换
:net切换到下一个文件
:previous切换到上一个文件
:last 最后一个
:first 第一个
退出所有文件
:wqall 保存所有文件并退出
:wall 保存所有文件
:qall 退出不保存所有文件
多窗口:
多文件
vim -o FILE1 FILE2 …
-o:水平分割窗口
-O:垂直分割窗口
窗口间切换Ctrl+w,Arrow(上下左右箭头)
单文件:(分割多个窗口)
Ctrl+w,s:水平分割
Ctrl+w,v:垂直分割
ctrl+w,q :取消相邻窗口
ctrl+w,o: 取消全部窗口
定制vim 的工作特性
末行模式(扩展模式):自此模式下的设定,仅对当前vim进程有效
配置文件:永久有效
全局:/etc/vimrc
个人:~/.vimrc(可能需要用户自己创建,格式逐一罗列每行一个)
(1)行号
显示:set number, 简写为set nu
取消显示:set nonumber, 简写为set nonu
(2)括号成对匹配高亮
匹配:set showmatch, 简写为set sm
取消:set noshowmatch, 简写为set nosm
(3)自动缩进
启用:set ai
禁用:set noai
(4)高亮搜索
启用:set hlsearch
禁用:set nohlsearch
(5)语法高亮
启用:syntax on
禁用:syntax off
(6)忽略字符的大小写
启用:set ic
不忽略:set noic
配置 vi and vim
(7)文件格式
启用windows 格式:set fileformat=dos
启用unix 格式:set fileformat=unix
(8)设置文本宽度
:set textwidth=65 (vim only)
:set wrapmargin=15
:help option-list
:set or :set all
vi/vim 内置帮助
:help
:help subject(关键词主题)
eg::help topic
:help set
练习和课后作业
1 、删除/etc/grub2.conf 文件中所有以空白开头的行行首的空白字符
sed "s/^[[:space:]]\+//" /etc/grub2.cfg
sed -r "s/^[[:space:]]+//" /etc/grub2.cfg
2 、删除/etc/fstab 文件中所有以# 开头,后面至少跟一个空白字符的行的行首的#和空白字符
sed -r "s/^#[[:space:]]+//" /etc/fstab
sed "s/^#[[:space:]]\+//" /etc/fstab
3 、在/root/install.log 每一行行首增加#号
sed -r "s/^.*/#&/" /root/install.log
sed -r "s/(.*)@#\1/g" /root/install.log
sed "s/^/#/" /root/install.log
4 、在/etc/fstab文件中不以#开头的行的行首增加#号
sed -r "s/^[^#]/#&/" /etc/fstab
5 、处理/etc/fstab路径, 使用sed 命令取出其目录名和基名
echo /etc/fstab | sed -r "s/^\/.*\<//" #基名
echo /etc/fstab | sed -r "s/([^/]+\/?)$//" #目录名
echo "/etc/fst/sd" | sed -r 's/(.*/)([^/]+/?)$/\1/' #基名用\2 目录名\1
6 、利用sed取出ifconfig 命令中本机的IPv4 地址
ifconfig | sed -n "2p" |sed -r "s/^[^:]+\://" | sed -r "s/[[:space:]].*//"
ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/'
ifconfig|sed -n 2p |sed -e 's/.*addr://' -e 's/ B.*//'
ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/'
7 、统计centos 安装光盘中Package 目录下的所有rpm 文件的以.分隔倒数第二个字段的重复次数
CentOS6.8
ls /media/CentOS_6.8_Final/Packages/*.rpm |egrep -o "[^.]+.rpm$"|egrep -o "^[^.]+\>"
ls /media/CentOS_6.8_Final/Packages/*.rpm |sed -r "s/\.rpm$//" | sed -r "s/.*\<//"
CentOS7.2
ls /run/media/root/CentOS\ 7\ x86_64/Packages/*.rpm |egrep -o "[^.]+.rpm$"|egrep -o "^[^.]+\>"
ls /run/media/root/CentOS\ 7\ x86_64/Packages/*.rpm |sed -r "s/\.rpm$//" | sed -r "s/.*\<//"
8、如何设置tab缩进为4个字符?
vim ~/.vimrc set tabstop=4 #tabstop=ts source ~/.vimrc
为了加强对比度,我们可以吧tabstop的值设为16,对比一下两者的效果
9、复制/etc/rc.d/init.d/functions文件至/tmp目录;替换/tmp/functions文件中的/etc/sysconfig/init为/var/log;
cp /etc/rc.d/init.d/functions /tmp vim /tmp/functions
用vim打开文件后按住shift键单击 :键 从命令模式(编辑模式)进去到插入模式(输入模式)
输入 %s@/etc/sysconfig/init@/var/log@gi 回车
再次进去插入模式(输入模式)
输入 wq 保存并退出
10、删除/tmp/functions文件中所有以#开头,且#后面至少有一个空白字符的行的行首的#号;
vim /tmp/functions
用vim打开文件后按住shift键单击 :键 从命令模式(编辑模式)进去到插入模式(输入模式)
输入 %s@^#\([[:space:]]\+.*\)@\1@g 回车
再次进去插入模式(输入模式)
输入 wq 保存并退出
未完待续
原创文章,作者:NameLess,如若转载,请注明出处:http://www.178linux.com/35052