文本处理:三剑客之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)

:x 保存退出

其他的一些用法

: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

赞 (0)
nieda_linuxnieda_linux
上一篇 2016-08-12 09:02
下一篇 2016-08-12 09:02

相关推荐

  • shell脚本编程之函数、case语句

    一、函数 调用函数前必须先定义,调用时仅使用函数名即可。 语法: function  函数名 {      函数体 } 也可表示为: 函数名 () { 函数体 } 示例:写一个脚本,判定网络内有哪些主机在线,在线的用绿色显示,不在线的用红示表示: c_net&…

    Linux干货 2015-08-24
  • 正则表达式简述

    bashshell中的正则表达式         俗话说,工欲善其事,必先利其器。由于很多Linux的文本处理工具普遍使用到了正则表达式,因此,不理解正则表达式就无法愉快的从事Linux日常系统管理。那什么是正则表达式呢?         正则表达式(Regu…

    Linux干货 2015-05-23
  • 第八周作业脚本练习

    1、写一个脚本,使用ping命令探测172.16.250.1-172.16.250.254之间的所有主机的在线状态;      在线的主机使用绿色显示;      不在线的主使用红色显示;          &…

    Linux干货 2017-02-01
  • DNS and BIND 配置指南

    前言     说来接触Linux也有一年了,BIND是我曾经学习RH系Linux接触的第一个服务,对我有着莫大的意义,当初差点因为这个服务难以配置而放弃Linux,今天学完马哥的bind相关系列视频之后,写一篇DNS and BIND的基础到进阶。 一、DNS的基础知识 DNS是什么? DNS(Domain Name …

    Linux干货 2016-03-21
  • mariadb基础应用

    mariadb基础应用 一、 前言 MariaDB is one of the most popular database servers in the world. It’s made by the original developers of MySQL and guaranteed to stay open source. Notable users …

    Linux干货 2016-12-16
  • 防火墙原理以及iptables重要实践

    防火墙 主机间通信大致过程: 请求报文由客户端IP+PORT和服务器端IP+PORT构成。当客户端网络地址和服务端地址在同一网段时,不需要经由路由转发,可以直接到目标服务器,再经由服务器端口请求道所需资源; 当服务器端和客户端不在同一网段时。目标IP和源IP是不会改变的,会经由互联网中的路由器,按照其的路由表,指向该路由器的下一跳主机,知道找到服务器端所在网…

    2017-06-18

评论列表(1条)

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

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