VIM和正規表示式

bestvae發表於2021-01-02

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:]]'`