文本处理:三剑客之sed及vim编辑器

一、sed的用法详解

sed作为Linux的第二招,有着非常强大的文本处理功能。sed是一种在线编辑器、行编辑器,每次处理一行内容。在处理时,sed首先将行放在内存中的一块临时缓冲区,通常配叫做模式空间(pattern space)。如果模式空间的行符合sed的匹配模式则将该行处理后送到标准输出,如果不匹配则不做任何改动送到标准输出。模式空间中一般情况下只会有一行的内容(用到保持空间的高级用法可能会有多行),所以非常适合处理大的文本。sed和grep虽然都是流式文本处理工具,grep主要用来检索条件关键字,sed则是根据检索匹配处理文本。

1470886429849697.jpg

sed的处理模式参考:

http://blog.oldboyedu.com/commands-sed/

  • sed的用法

sed [OPTIONS]… {script} [input-filer]… [actions]

  • 常用选项:

-r:支持扩展正则表达式

-n:静默模式,不打印任何信息,除非使用p

-e:指定多个脚本运行

-f:从指定脚本读取脚本

-i:直接修改原文件

  • sed的地址定界:

#:#为数字,指定行

$:最后一行

/pattern/:被匹配到的每一行

地址范围:

#,#:#是数字,表示从某行到某行

#,+#:某行及其接下来的几行

/pat1/,/pat2/:第一次匹配的pat1行到第一次匹配的pat2行

#,/pat1/:从某行到接下来第一次匹配的pat1行

~:步长,1~2所有奇数行,2~2所有偶数行

  • 编辑命令:

d:删除模式空间匹配的行

p: 显示模式空间中的内容

a:在行后面追加文本;支持使用\n实现多行追加

i:在行前面插入文本;支持使用\n实现多行插入

c :替换行为单行或多行文本

w /path: 保存模式匹配的行至指定文件

r /path:读取指定文件的文本至模式空间中匹配到的行后

=: 为模式空间中的行打印行号

!:模式空间中匹配行取反处理

s///:查找替换,支持使用其它分隔符,s@@@,s###,通常在s前加%进行全文匹配。在最后可以加g:行内全局替换;p:显示替换成功的行;w /path:将替换成功的行保存到某文件

  • sed的高级编辑命令:

h: 把模式空间中的内容覆盖至保持空间中
H:把模式空间中的内容追加至保持空间中
g: 从保持空间取出数据覆盖至模式空间
G:从保持空间取出内容追加至模式空间
x: 把模式空间中的内容与保持空间中的内容进行互换
n: 读取匹配到的行的下一行覆盖至模式空间
N:追加匹配到的行的下一行至模式空间
d: 删除模式空间中的行
D:删除当前模式空间开端至\n的内容(不在传至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed

注意:保持空间是sed高级用法的概念,在一般命令中用不到保持空间

二、vim编辑器

作为Linux中功能最强大的编辑器,vim的熟练使用势必成为运维人员的标准配置。vim有复杂的快捷键功能,许多工作多年的运维工程师也不敢说能够完全驾驭vim,但熟练使用vim绝对可以帮助我们节省大量的时间。

vim有六种模式(不同的版本可能不同可以通过vim的帮助文档查看),但主要使用的只有三种:

  • 命令模式:Linux的默认模式,可以移动光标并对文本粘贴复制

  • 插入模式:编辑文件

  • 扩展命令模式:在命令模式中键入:进入,可以批量修改并搜索关键字,可以设置当前文本的vim环境配置,保存退出

从默认的命令模式进入插入模式:

i:在当前光标处插入

I:在光标所在行的行首插入

a:在光标后插入

A:在当前光标所在行的行尾输入

o: 在当前光标所在行的下方打开一个新行
O:在当前光标所在行的上方打开一个新行

锁定界面并解锁:

ctrl+s:锁定界面,但实质上任然可以操作

ctrl+q:解锁,从锁定到解锁之间的操作都有效

  • 退出并保存文件

在扩展命令模式下:
:w filename (输入 「w filename」将文章以指定的文件名filename保存)
:wq (输入「wq」,存盘并退出vi)
:q! (输入q!, 不存盘强制退出vi)

😡 保存退出

其他的一些用法

:r filename 读文件内容到当前文件中
:w filename 将当前文件内容写入另一个文件
:!command 在vim中执行命令行命令并显示结果不会对当前打开的文件产生任何影响
:r!command 将命令行下的命令输出结果写到光标处,不能支持复杂的用法如sed的高级用法不支持

在命令模式下:

ZZ: 保存退出

ZQ:不保存退出

其他的用法:

h:左移光标一个字符
l:右移光标一个字符
k:光标上移一行
j:光标下移一行
^:光标移动至行首
0:数字“0”,光标移至文章的开头
G:光标移至文章的最后
$:光标移动至行尾
Ctrl+f:向前翻屏
Ctrl+b:向后翻屏
Ctrl+d:向前翻半屏
Ctrl+u:向后翻半屏
x:删除光标后面的字符
#x:删除光标后的#个字符
X:删除光标前面的字符
#X:删除光标前面的#个字符
dd:删除光标所在的行
#dd:删除从光标所在行数的#行
yw:复制光标所在位置的一个字
#yw:复制光标所在位置的#个字
yy:复制光标所在位置的一行
#yy:复制从光标所在行数的#行
p:粘贴
u:取消操作
cw:更改光标所在位置的一个字
#cw:更改光标所在位置的#个字

其中y、d和c的用法大致相同

  • 扩展模式下的地址定界:

#: 具体第#行,例如2表示第2行;
#,#: 从左侧#表示行起始,到右侧#表示行结尾
#,+#: 从左侧#表示的行起始,加上右侧#表示的行数
:2,+3 表示2到5行
.: 当前行
$: 最后一行
.,$-1 当前行到倒数第二行
%:全文, 相当于1,$

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

查找替换操作:

注意:替换为的内容:不能使用模式,但可以使用\1, \2, …等后向引用符号;还可以使用“&”引用前面查找时查找到的整个内容

格式有:s///或s@@@、s###,和sed的用法相同

后面可以加修饰符:
i: 忽略大小写
g: 全局替换;默认情况下,每一行只替换第一次出现
gc:全局替换,每次替换前询问

  • vim的寄存器:

有26个命名寄存器和1个无命名寄存器,常存放不同的剪贴版内容,可以不同会话间共享。
用a,b,…,z表示,用“寄存器表示,放在数字和命令之间
如:3"tyy 表示复制3行到t寄存器中
"tp 表示将t寄存器内容粘贴
未指定,将使用无命名寄存器
有10个数字寄存器,用0,1,…,9表示,0存放最近复制内容,1存放最近删除内容。当新的文本变更和删除时,1转存到2,2转存到3,以此类推。数字寄存器不能在不同会话间共享。

  • vim编辑二进制文件:

vim –b binaryfile

扩展命令模式下,利用xxd命令转换为可读的十六进制
:%!xxd

扩展命令模式下,利用xxd命令转换回二进制
:%!xxd –r

  • vim的可视化编辑

v面向字符
V面向行
ctrl-v 面向块
可视化键可用于与移动键结合使用:w,),},箭头等

突出显示的文字可以被删除,复制,变更,过滤,搜索/替换等

如:要给连续的行前加注释

1470893517753275.png

ctrl+v进入视图模式,选中要加注释行的所有第一个字母,shift+i+#,按住shift再按i和#号然后送开所有的键再按esc就可以批量加#号

  • vim可以多文件编辑:

:next 下一个
:prev前一个
:first 第一个
:last 最后一个
:wall 保存所有
:qall退出所有
:wqall

  • vim多窗口编辑

vim -o|O file1 file2,,,

-o:水平分割

-O:垂直分割

在窗口间切换:ctrl+w

单文件分割:

Ctrl+w,s: split, 水平分割
Ctrl+w,v: vertical, 垂直分割
ctrl+w,q:取消相邻窗口
ctrl+w,o:取消全部窗口
:wqall退出

  • vim的配置文件:

全局:/etc/vimrc

个人:~/.vimrc

1、行号

set number,简写set nu或se nu

取消显示行号:set nonumber,简写set nonum或se nonu

2、括号匹对

set showmatch 简写:set sm或se sm(在7里以默认为开启)

取消:set nosm

3、自动缩进

启用:set ai

取消:set noai

4、高亮搜索

启用:set hlsearch

取消:set nohlsearch 可以直接nohl取消高亮

5、语法高亮

syntax on

syntax off

6、忽略字符的大小写

忽略:set ic

不忽略:set noic

7、文件格式

fileformat=unix

fileformat=dos

8、设置文本宽度

set textwidth=65(只有vim有),从左往又数,默认为80个字符

set wrapmargin=15 从右往左数,和上面的等价

…..

vim的用法在shell里有详细的介绍:

命令行输入vim进入vim的帮助文档,set all可以查看所有的vim设置

练习及作业:

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

[root@localhost ~]# sed -r 's/^[[:space:]]+//g' /etc/grub2.cfg 
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
set pager=1
if [ -s $prefix/grubenv ]; then
load_env
......

2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符

[root@localhost ~]# sed -r 's@^#[[:space:]]+\b@@g' /etc/fstab 
#
# /etc/fstab
Created by anaconda on Wed Aug  3 06:08:10 2016
#
Accessible filesystems, by reference, are maintained under '/dev/disk'
See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=1aa7af5a-15a0-4cf2-a11d-8304d67c7093 /                       xfs     defaults        0 0
UUID=2fb41265-5d13-4ef0-82f6-3147009bd1a5 /boot                   xfs     defaults        0 0
UUID=a5a6b450-ba91-4e5b-a5ad-a17e12a2a994 /testdir                xfs     defaults        0 0
UUID=1d6f94c4-7eb4-430c-b143-b63b498c1c98 swap                    swap    defaults        0 0

3、在/root/install.log每一行行首增加#号

[root@localhost ~]# sed 's/^/#/g' /etc/fstab

#
##
## /etc/fstab
## Created by anaconda on Wed Aug  3 06:08:10 2016
##
## Accessible filesystems, by reference, are maintained under '/dev/disk'
## See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
##
#UUID=1aa7af5a-15a0-4cf2-a11d-8304d67c7093 /                       xfs     defaults        0 0
#UUID=2fb41265-5d13-4ef0-82f6-3147009bd1a5 /boot                   xfs     defaults        0 0
#UUID=a5a6b450-ba91-4e5b-a5ad-a17e12a2a994 /testdir                xfs     defaults        0 0
#UUID=1d6f94c4-7eb4-430c-b143-b63b498c1c98 swap                    swap    defaults        0 0

4、在/etc/fstab文件中不以#开头的行的行首增加#号

[root@localhost ~]# sed 's/^[^#]/#&/g' /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Wed Aug  3 06:08:10 2016
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
#UUID=1aa7af5a-15a0-4cf2-a11d-8304d67c7093 /                       xfs     defaults        0 0
#UUID=2fb41265-5d13-4ef0-82f6-3147009bd1a5 /boot                   xfs     defaults        0 0
#UUID=a5a6b450-ba91-4e5b-a5ad-a17e12a2a994 /testdir                xfs     defaults        0 0
#UUID=1d6f94c4-7eb4-430c-b143-b63b498c1c98 swap                    swap    defaults        0 0

注意:最上面的回车换行没有加#,即没有匹配回车换行

[root@localhost ~]# sed  '/^#/p;s/^[^#]/#&/pg;/^#/d;s/^/#/'  /etc/fstab 
#
#
# /etc/fstab
# Created by anaconda on Wed Aug  3 06:08:10 2016
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
#  
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
#UUID=1aa7af5a-15a0-4cf2-a11d-8304d67c7093 /                       xfs     defaults        0 0
#UUID=2fb41265-5d13-4ef0-82f6-3147009bd1a5 /boot                   xfs     defaults        0 0
#UUID=a5a6b450-ba91-4e5b-a5ad-a17e12a2a994 /testdir                xfs     defaults        0 0
#UUID=1d6f94c4-7eb4-430c-b143-b63b498c1c98 swap                    swap    defaults        0 0
[root@localhost ~]# sed -r 's/^([^#]|$)/#&/' /etc/fstab 
#
#
# /etc/fstab
# Created by anaconda on Wed Aug  3 06:08:10 2016
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
#  
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
#UUID=1aa7af5a-15a0-4cf2-a11d-8304d67c7093 /                       xfs     defaults        0 0
#UUID=2fb41265-5d13-4ef0-82f6-3147009bd1a5 /boot                   xfs     defaults        0 0
#UUID=a5a6b450-ba91-4e5b-a5ad-a17e12a2a994 /testdir                xfs     defaults        0 0
#UUID=1d6f94c4-7eb4-430c-b143-b63b498c1c98 swap                    swap    defaults        0 0

5、处理/etc/fstab路径,使用sed命令取出其目录名和基名

[root@localhost ~]# echo "/etc/init.d/functions" |sed 's/.*\<//'
functions
[root@localhost ~]# echo "/etc/init.d/functions" |sed -r 's@[^/]+.?$@@g'
/etc/init.d/
[root@localhost ~]# echo "/etc/init.d/functions" |sed -r 's@(.*)/([^\]+.?)$@\1@g'
/etc/init.d
[root@localhost ~]# echo "/etc/init.d/functions" |sed -r 's@(.*)/([^\]+.?)$@\2@g'
functions

6、利用sed 取出ifconfig命令中本机的IPv4地址

[root@localhost ~]# ifconfig |sed -r '/^[^ ]/!d;N;s/^([^ ]+).*\n[^0-9]+([0-9.]+).*/\1 \2/'
eno16777736: 10.1.70.102
lo: 127.0.0.1
virbr0: 192.168.122.1

7、统计centos安装光盘中Package目录下的所有rpm文件的以.分隔倒数第二个字段的重复次数

[root@localhost ~]# ls /mnt/Packages/ |sed -r 's/.*\b([^.]+)\.[^.]+$/\1/'|sort|uniq -c
   2000 i686
   2938 noarch
      1 TRANS
   4069 x86_64
[root@localhost ~]# ls /mnt/Packages/|rev|cut -d. -f2|rev|sort|uniq -c
   2000 i686
   2938 noarch
      1 TRANS
   4069 x86_64

1、如何设置tab缩进为4个字符?

:set ts=4

2、复制/etc/rc.d/init.d/functions文件至/tmp目录;替换/tmp/functions文件中的/etc/sysconfig/init为/var/log

:%s@/etc/sysconfig/init@/var/log@g

3、删除/tmp/functions文件中所有以#开头,且#后面至少有一个空白字符的行的行首的#号

:%s/^# / /g

原创文章,作者:nieda_linux,如若转载,请注明出处:http://www.178linux.com/33221

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-12 12:22

    文章结构清晰,有理有据,图文并貌。