VIM和正则表达式

1.VIM

1.1vim简介

vim是一款强大的文本编辑器,它和 vi 使用方法一致,但功能更为强大。官网:www.vim.org、中文手册:http://vimcdoc.sourceforge.net/

1.2使用vim

1.2.1命令格式

vim [options] [file ..]

常用选项

  • +# 打开文件后,让光标处于第#行的行首,+默认行尾
  • +/PATTERN 让光标处于第一个被PATTERN匹配到的行行首
  • -d file1 file2… 比较多个文件,相当于 vimdiff

说明:当使用vim打开文件的时候,如果该文件存在,文件被打开并显示内容。如果该文件不存在,当编辑后第一次存盘时创建它

1.2.2vim三种模式的切换

三种模式分为

命令或普通模式、插入模式、扩展模式

  • 命令模式 --> 插入模式
i insert, 在光标所在处输入
I 在当前光标所在行的行首输入
a append, 在光标所在处后面输入
A 在当前光标所在行的行尾输入
o 在当前光标所在行的下方打开一个新行
O 在当前光标所在行的上方打开一个新行
  • 插入模式 --- ESC-----> 命令模式
  • 命令模式 ---- : ----> 扩展命令模式
  • 扩展命令模式 ----ESC,enter----> 命令模式

1.3扩展命令模式

1.3.1 基本命令
w 		写(存)磁盘文件
wq 写入并退出
x 写入并退出加密
q 退出,如果修改了内容无法退出
q! 强制不存盘退出,即使更改都将丢失
r filename 读文件内容到当前文件中
!command 执行命令
r!command 读入命令的输出
1.3.2 地址定界

格式

:start_pos,end_pos CMD

地址定界符

# 			#具体第#行,例如2表示第2行
#,# #从左侧#表示起始行,到右侧#表示结尾行
#,+# #从左侧#表示的起始行,加上右侧#表示的行数,范例:2,+3 表示2到5行
. #当前行
$ #最后一行
.,$-1 #当前行到倒数第二行
% #全文, 相当于1,$ /pattern/ #从当前行向下查找,直到匹配pattern的第一行,即:正则表达式
/pat1/,/pat2/ #从第一次被pat1模式匹配到的行开始,一直到第一次被pat2匹配到的行结束
#,/pat/ #从指定行开始,一直找到第一个匹配patttern的行结束
/pat/,$ #向下找到第一个匹配patttern的行到整个文件的结尾的所有行

地址定界后可跟一个编辑命令

d       	#删除
y #复制
w file #将范围内的行另存至指定文件中
r file #在指定位置插入指定文件中的所有内容
1.3.3 查找和替换
s/要查找的内容/替换为的内容/修饰符

说明

要查找的内容:可使用基末正则表达式模式
替换为的内容:不能使用模式,但可以使用\1, \2, ...等后向引用符号;还可以使用“&”引用前面查找时查
找到的整个内容

修饰符:

i #忽略大小写
g #全局替换,默认情况下,每一行只替换第一次出现
gc #全局替换,每次替换前询问

查找替换中的分隔符/可替换为其它字符,如:#,@

s@/etc@/var@g
s#/boot#/#i
1.3.4 定制vim

配置文件:

/etc/vimrc #全局
~/.vimrc #个人 #行号
显示:set number,简写 set nu
取消显示:set nonumber, 简写 set nonu #忽略字符的大小写
启用:set ignorecase,简写 set ic
不忽略:set noic #自动缩进
启用:set autoindent,简写 set ai
禁用:set noai #设置光标所在行的标识线
启用:set cursorline,简写 set cul
禁用:set nocursorline #Tab用指定空格的个数代替
启用:set tabstop=# 指定#个空格代替Tab
简写:set ts=4 #文件格式
启用windows格式:set fileformat=dos
启用unix格式:set fileformat=unix
简写 set ff=dos|unix #Tab 用空格代替
启用:set expandtab 默认为8个空格代替Tab
禁用:set noexpandtab
简写:set et #语法高亮
启用:syntax on
禁用:syntax of #高亮搜索
启用:set hlsearch
禁用:set nohlsearch #显示Tab和换行符 ^I 和$显示
启用:set list
禁用:set nolist #set showcmd
显示命令模式下输入的字符

1.4 命令模式

1.4.1 退出VIM

ZZ | wq 保存退出

ZQ | q 不保存退出

1.4.2 光标跳转

字符间跳转:

h: 左 L: 右 j: 下 k: 上

COMMAND:跳转由#指定的个数的字符

单词间跳转:

w:下一个单词的词首

e:当前或下一单词的词尾

b:当前或前一个单词的词首

COMMAND:由#指定一次跳转的单词数

当前页跳转:

H:页首 M:页中间行 L:页底

zt:将光标所在当前行移到屏幕顶端

zz:将光标所在当前行移到屏幕中间

zb:将光标所在当前行移到屏幕底端

行首行尾跳转:

^ 跳转至行首的第一个非空白字符

0 跳转至行首

$ 跳转至行尾

行间移动:

#G 或者扩展命令模式下 :# 跳转至由第#行

G 最后一行

1G, gg 第一行

命令模式翻屏操作

Ctrl+f 向文件尾部翻一屏

Ctrl+b 向文件首部翻一屏

Ctrl+d 向文件尾部翻半屏

Ctrl+u 向文件首部翻半屏

1.4.3 字符编辑

x 删除光标处的字符

x 删除光标处起始的#个字符

xp 交换光标所在处的字符及其后面字符的位置

1.4.4 替换命令(replace)

r 只替换光标所在处的一个字符

R 切换成REPLACE模式(在末行出现-- REPLACE -- 提示),按ESC回到命令模式

1.4.5 删除命令(delete)

d 删除命令,可结合光标跳转字符,实现范围删除

d$ 删除到行尾

d^ 删除到非空行首

d0 删除到行首

dd: 剪切光标所在的行

dd 多行删除

D:从当前光标位置一直删除到行尾,等同于d$

1.4.6 复制命令(yank)

y 复制,行为相似于d命令

1.4.7 粘贴命令(paste)

p 缓冲区存的如果为整行,则粘贴当前光标所在行的下方;否则,则粘贴至当前光标所在处的后面

P 缓冲区存的如果为整行,则粘贴当前光标所在行的上方;否则,则粘贴至当前光标所在处的前面

1.4.8 改变命令(change)

c: 删除后切换成插入模式

c$

c^

c0

cb

1.4.9 查找

/PATTERN:从当前光标所在处向文件尾部查找

?PATTERN:从当前光标所在处向文件首部查找

n:与命令同方向

N:与命令反方向

1.4.10 撤消更改

u 撤销最近的更改,相当于windows中ctrl+z

#u 撤销之前多次更改

U 撤消光标落在这行后所有此行的更改

Ctrl - r 重做最后的“撤消”更改,相当于windows中crtl+y

. 重复前一个操作

. 重复前一个操作#次

1.4.11 高级用法

常见Command:y 复制、d 删除、gU 变大写、gu 变小写

范例

0y$ 命令
#粘贴一个字符100次
100ihello [ESC]

di" 光标在” “之间,则删除” “之间的内容

yi( 光标在()之间,则复制()之间的内容

vi[ 光标在[]之间,则选中[]之间的内容

dtx 删除字符直到遇见光标之后的第一个 x 字符

ytx 复制字符直到遇见光标之后的第一个 x 字符

1.5 可视化模式

在末行有”-- VISUAL -- “指示,表示在可视化模式

进入可视化模式按键

  • v 面向字符,-- VISUAL --
  • V 面向整行,-- VISUAL LINE --
  • ctrl-v 面向块,-- VISUAL BLOCK --

1.6 多文件模式

vim FILE1 FILE2 FILE3 ...

:next 下一个

:prev 前一个

:first 第一个

:last 最后一个

:wall 保存所有

:qall 不保存退出所有

:wqall保存退出所有

1.7 多窗口模式

1.7.1 多文件分割

vim -o|-O FILE1 FILE2 ...

-o: 水平或上下分割

-O: 垂直或左右分割(vim only)

在窗口间切换:Ctrl+w+方向键

1.7.2 单文件窗口分割

Ctrl+w+s:split, 水平分割,上下分屏

Ctrl+w+v:vertical, 垂直分割,左右分屏

ctrl+w+q:取消相邻窗口

ctrl+w+o:取消全部窗口

:wqall 退出

1.8 vim寄存器

有26个命名寄存器和1个无命名寄存器,常存放不同的剪贴版内容,可以在同一个主机的不同会话(终 端窗口)间共享

寄存器名称a,b,…,z,格式: ”寄存器 放在数字和命令之间

范例:

3"tyy 表示复制3行到t寄存器中 ,末行显示 3 lines yanked into "t
"tp 表示将t寄存器内容粘贴

1.9 标记和宏(macro)

ma 将当前位置标记为a,26个字母均可做标记, mb 、 mc 等等

'a 跳转到a标记的位置,实用的文档内标记方法,文档中跳跃编辑时很有用

qa 录制宏 a,a为宏的名称,末行提示: recording @a

q 停止录制宏

@a 执行宏 a

@@ 重新执行上次执行的宏

2 文本常见处理工具

2.1查看文件内容

2.1.1 cat

cat 可以查看文本内容

cat [OPTION]... [FILE]...

常见选项

  • -E:显示行结束符$
  • -A:显示所有控制符
  • -n:对显示出的每一行进行编号
  • -b:非空行编号
  • -s:压缩连续的空行成一行
2.1.2 nl

nl:显示行号,相当于cat -b

nl [OPTION]... [FILE]...
2.1.3 tac

tac:逆向显示文本内容

tac [OPTION]... [FILE]...
2.1.4 rev

rev:将同一行的内容逆向显示

rev [option] [file...]
[root@centos8 data]# rev lx.txt
ba321
[root@centos8 data]# cat lx.txt
123ab
2.1.5 hexdump

hexdump:以十六进制,十进制,八进制或ASCII显示文件内容

hexdump [options] file...

-C 十六进制+ASCII显示
[root@centos8 data]# hexdump -C lx.txt
00000000 31 32 33 61 62 0a |123ab.|
00000006
[root@centos8 data]# cat lx.txt
123ab

2.2分页查看文本内容

2.2.1 more

more:分页查看文件(文本翻至尾部就会自动退出)

more [options] file...

常见选项

  • -d 显示翻页以及退出提示
2.2.2 less

less:分页查看文件(文本末页不会自动退出)

less 命令是man命令使用的分页器

[root@centos8 data]# cat passwd | less

2.3 显示文本前或后行内容

2.3.1 head

head:显示文件或者标准输入前面内容

head [OPTION]... [FILE]...

常见选项

  • -c # 指定获取前#字节
  • -n # 指定获取前#行
  • -# 同上

范例

[root@centos8 data]# head -2 lx.txt
1
2
2.3.2 tail

tail:和head 相反,查看文件或标准输入的倒数行

tail [OPTION]... [FILE]...

常用选项

  • -c # 指定获取后#字节
  • -n # 指定获取后#行
  • -# 同上
  • -f 跟踪显示文件fd新追加的内容,常用日志监控,相当于 --follow=descriptor,当文件删除再新建同名 文件,将无法继续跟踪文件
  • -F 跟踪文件名,相当于--follow=name --retry,当文件删除再新建同名文件,将可以继续跟踪文件
  • tailf 类似 tail –f,当文件不增长时并不访问文件

范例

[root@centos8 data]# tail -2 /data/lx.txt
9
10
#只查看最新发生的日志
[root@centos8 data]# tail -fn0 /data/lx.txt
ab

2.4 cut

cut:提取文本文件或者STDIN数据指定列

cut OPTION... [FILE]...

常用选项

  • -d DELIMITER: 指明分隔符,默认tab

  • -f FILEDS:

    ​ #: 第#个字段,例如:3

    ​ #,#[,#]:离散的多个字段,例如:1,3,6

    ​ #-#:连续的多个字段, 例如:1-6

    ​ 混合使用:1-3,7

  • -c 按字符切割

  • --output-delimiter=STRING指定输出分隔符

范例

#查看主机IP地址
[root@centos8 data]# ifconfig | head -2 | tail -1 | tr -s ' ' | cut -d' ' -f3
172.22.73.89
#显示df命令中磁盘使用率
[root@centos8 data]# df | tr -s ' ' | cut -d' ' -f5 | tr -dc '[0-9\n]'
0
0
[root@centos8 data]# df | tr -s ' ' % | cut -d% -f5 | tr -d [:alpha:] 0
0

2.5 paste

paste:合并多个文件同行号列到一行

paste [OPTION]... [FILE]...

常用选项

  • -d 分隔符:指定分隔符,默认用TAB
  • -s : 所有行合成一行显示

2.6 文本分析工具

2.6.1 wc

wc:统计文件的行总数、单词总数、字节总数和字符总数

wc [OPTION]... [FILE]...

常用选项

  • -l 只计数行数
  • -w 只计数单词总数
  • -L 显示文件中最长行的长度
[root@centos8 data]# wc -l lx.txt
2 lx.txt
2.6.2 sort

sort:把整理过的文本显示在STDOUT,不改变原始文件

sort [OPTION]... [FILE]...

常用选项

  • -r 执行反方向(由上至下)整理
  • -R 随机排序
  • -n 执行按数字大小整理
  • -u 选项(独特,unique),合并重复项,即去重
  • -t c 选项使用c做为字段界定符
  • -k 指定排序的关键字

范例

#统计日志访问量
[root@centos8 data]#cut -d" " -f1 /var/log/nginx/access_log |sort -u|wc -l
201 [root@centos8 data]# cut -d: -f1,3 passwd | sort -k2 -nr | head -5
user3:2004
user2:2003
user1:1002
user:1001
unbound:996
2.6.3 uniq

uniq:命令从输入中删除前后相接的重复的行

uniq [OPTION]... [INPUT [OUTPUT]]

常用选项

  • -c: 显示每行重复出现的次数
  • -d: 仅显示重复过的行
  • -u: 仅显示不曾重复的行

uniq常和sort 命令一起配合使用:

范例

#统计日志访问量最多的请求
[root@centos8 data]# cut -d" " -f1 access_log | sort | uniq -c | sort -nr | head -1
2834 172.20.0.222 #取两个文件的相同行
[root@centos8 data]# cat a.txt b.txt | sort | uniq -d
200
#取两个文件的不同行
[root@centos8 data]# cat a.txt b.txt | sort | uniq -u
100
123
23
3321
34556
2.6.4 diff

diff:令比较两个文件之间的区别

diff [OPTION]... FILES

[root@centos8 data]# cat a.txt b.txt
a
b
c
a
b
bc
[root@centos8 data]# diff a.txt b.txt
3c3
< c
---
> bc

3 正则表达式

正则表达式分两类:

​ 基本正则表达式:BRE

​ 扩展正则表达式:ERE

​ 帮助:man 7 regex

3.1 基本正则表达式元字符

与通配符不同,通配 符功能是用来处理文件名,而正则表达式是处理文本内容中字符

3.1.1 字符匹配
.   匹配任意单个字符,可以是一个汉字
[] 匹配指定范围内的任意单个字符,示例:[wang] [0-9] [a-z] [a-zA-Z]
[^] 匹配指定范围外的任意单个字符,示例:[^wang] [:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
3.1.2 匹配次数
* 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* 任意长度的任意字符
\? 匹配其前面的字符0或1次,即:可有可无
\+ 匹配其前面的字符至少1次,即:肯定有,>=1
\{n\} 匹配前面的字符n次
\{m,n\} 匹配前面的字符至少m次,至多n次
\{,n\} 匹配前面的字符至多n次,<=n
\{n,\} 匹配前面的字符至少n次
3.1.3 位置锚定
^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
\< 或 \b 词首锚定,用于单词模式的左侧
\> 或 \b 词尾锚定,用于单词模式的右侧
\<PATTERN\> 匹配整个单词
3.1.4 分组其它

分组

分组:() 将多个字符捆绑在一起,当作一个整体处理,如:(root)+ 后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名 方式为: \1, \2, \3, ...

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

或者

a\|b #a或b
C\|cat #C或cat
\(C\|c\)at #Cat或cat

3.2 扩展正则表达式

扩展正则于正则用法基本相同,大部分扩展正则相比正则只是取消了反斜线

3.2.1 字符匹配元字符
. 任意单个字符
[wang] 指定范围的字符
[^wang] 不在指定范围的字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
3.2.2 次数匹配
*   匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
3.2.3 位置锚定
^ 行首
$ 行尾
\<, \b 语首
\>, \b 语尾
3.2.4 分组其它
() 分组
后向引用:\1, \2, ...
| 或者
a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat

4 文本处理三剑客

4.1 grep

grep:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行

grep [OPTIONS] PATTERN [FILE...]

常用选项

  • -v 显示不被pattern匹配到的行
  • -i 忽略字符大小写
  • -n 显示匹配的行号
  • -c 统计匹配的行数
  • -f file 根据模式文件处理
  • -E 使用ERE,相当于egrep
  • -o 仅显示匹配到的字符串
  • -e 实现多个选项间的逻辑or关系,如:grep –e ‘cat ’ -e ‘dog’ file

范例

[root@centos8 data]# grep "whoami" /etc/passwd
[root@centos8 data]# grep `whoami` /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin #文件匹配
[root@centos8 data]# cat a.txt b.txt
a
b
c
a
b
d
[root@centos8 data]# grep -f a.txt b.txt
a
b #查看磁盘最高使用率
[root@centos8 data]# df | grep ^/dev/vd | tr -s " " % | cut -d% -f5
7 #计算出所有人年龄之和
[root@centos8 data]# cat lx.txt
xiaoming=20
xiaodong=18
xiaoqiang=22
[root@centos8 data]# cut -d= -f2 lx.txt | tr "\n" + | grep -Eo .*[0-9] | bc
60
[root@centos8 data]# grep -Eo [0-9]+ /data/lx.txt | tr "\n" + | grep -Eo .*[0-9] | bc
60

练习

1.统计出/etc/passwd文件中默认其shell为非/sbin/nologin的用户个数,并将用户都显示出来
[root@centos8 data]# cat /etc/passwd | grep -v /sbin/nologin | cut -d: -f1
root
user
user1
slackware
user2
user3
2.查出用户UID的最大值的用户名、UID及shell类型
[root@centos8 data]# cut -d: -f1,3,7 /etc/passwd | sort -k2 -nr | head -1
user3:2004:/bin/bash
3.统计当前连接本机的每个远程主机IP的连接数,并按从小到大排序
[root@centos8 data]# ss -nt | grep ^ESTAB | tr -s " " : | cut -d: -f6 | sort -nr
110.152.191.166
100.100.30.25
4.编写脚本disk.sh,显示当前硬盘分区中空间利用率最大的值
[root@centos8 data]# cat lx.txt
#/bin/bash!
df | grep /dev/vd | tr -s " " % | cut -d% -f5
5.编写脚本systeminfo.sh,显示当前主机系统信息,包括:主机名,ipv4地址,操作系统版本,内核版本,cpu型号,内存大小,硬盘大小
1 #/bin/bash!
2 echo 主机名`hostname`
3 echo 地址`ifconfig | head -3 | tail -2 | tr -s " " % | cut -d% -f3 | head -1`
4 echo 操作系统版本`cat /etc/redhat-release`
5 echo 内核版本`uname -r`
6 echo cpu型号`cat /proc/cpuinfo | grep "model name" | cut -d: -f2`
7 echo 内存大小 "`free -h | grep ^Mem | tr -s " " % | cut -d% -f2`"
8 echo 硬盘大小`lsblk | grep 'vda\>' | grep -Eo '[0-9]+[[:upper:]]'`
上一篇:我的tensorflow学习1


下一篇:vim的正则表达式(二)应用实例