目錄
一、正則表達式
1.1、字符匹配
1.2、次數匹配
1.3、位置錨定
1.4、分組或其他
二、擴展正則表達式
三、grep
四、awk
4.1、常用命令選項
4.2、工作原理
?4.3、基礎用法
4.4、內置變量
4.5、模式
4.6、條件判斷
4.7、awk中的循環語句
4.8、數組
4.9、腳本
五、sed
5.1、sed腳本格式
?5.2、sed命令
5.3、搜索替換
5.4、分組后向引用
一、正則表達式
正則表達式,又稱規則表達式。(英語:Regular Expression),在代碼中常簡寫為 regex、regexp 或 RE),計算機科學的一個概念。正則表達式通常被用來檢索、替換那些符合某個模式(規則)的文本。
正則表達式不只有一種,而且linux中不同的程序可能會使用不同的正則表達式,如:grep sed awk egrep?
LINUX 中常用的有兩種正則表達式引擎:
- 基礎正則表達式:BRE
- 擴展正則表達式: ERE
通配符與正則表達式的區別:
- 通配符一般用于文件名匹配
- 正則表達式一般用于匹配文件內容
1.1、字符匹配
元字符 | 定義 |
. | 匹配除換行符\n之外的任意單個字符 |
[? ?] | 匹配中括號內任意單個字符 |
[^ ] | 匹配除中括號內任意單個字符 |
[:alnum:] | 數字和字母 |
[:alpha:] | 任意大小寫英文字符 |
[:lower:] | 小寫字母 |
[:upper:] | 大寫字母 |
[:blank:] | 空白字符(空格和制表符) |
[:space:] | 空格、制表符、換行符、回車符等空白 |
[:cntrl:] | 不可打印的控制字符(退格、刪除、警鈴等) |
[:digit:] | 十進制數字 |
[:xdigit:] | 十六進制數字 |
[:graph:] | 可打印的非空白字符 |
[:print:] | 可打印字符 |
[:punct:] | 標點符號 |
\w | 匹配單詞? |
\W | |
\s | |
\S |
1.2、次數匹配
元字符 | 定義 |
* | 匹配前面字符人任意次,包括0次 |
.* | 任意長度的任意字符,不包括0次 |
\? | 匹配前面字符出現0次或1次 |
\+ | 前面字符出現最少1次 |
\{n\} | 匹配前面字符n次 |
\{m,n\} | 匹配前面字符最少m次,最多n次 |
\{,n\} | 匹配前面字符最多n次,≤n |
\{n,\} | 匹配前面字符最少n次 |
1.3、位置錨定
元字符 | 定義 |
^ | 行首錨定,用于模式最左側 |
$ | 行尾錨定,用于模式最右側 |
^PATTTERN$ | 匹配整行 |
^$ | 空行,不包括空格行 |
^[:space:]*$ | 空白行 |
\b,\< | 詞首錨定,用于模式最左側 |
\b,\> | 詞尾錨定,用于模式最右側 |
1.4、分組或其他
元字符 | 定義 |
(????????) | 分組,將多個字符作為一個整體 |
(x\|y) | 由左向右匹配指定字符 |
二、擴展正則表達式
通常情況下會使用基礎正則表達式就已經足夠了,但有時為了簡化整個指令,需要使用 ?范圍更廣的擴展正則表達式。
#次數匹配
* #前面任意字符
? #0或1次
+ #1次以上
{n} #匹配n次
{m,n} #最少m次,最多n次
{,n} #前面字符最多n次,≤n
{n,} #前面字符最少n次
#分組匹配
() #多個字符當作整體處理
\1,\2,... #向后引用
| #或
三、grep
語法格式:grep 參數 文件名
常用參數:
-m<x> | 找到x行后停止查找 |
-v | 取反 |
-i | 忽略大小寫 |
-n | 顯示行號 |
-c | 統計行數 |
-o | 僅顯示匹配到的字符 |
-q | 靜默模式,不輸出任何信息 |
-A<x> | 顯示匹配行,及之后的x行 |
-B | 顯示匹配行,及之前的x行 |
-C | 顯示匹配行,及前后x行 |
-e | 多個選項間的邏輯或 |
-E | 使用擴展正則表達式 |
-w | 只顯示全字符合的列 |
-F | 不使用正則表達式 |
-f | 處理兩個文件相同內容,以第一個文件為匹配條件 |
-r | 遞歸目錄,不處理軟鏈接 |
-R | 遞歸目錄,處理軟連接 |
--color=auto | 高亮匹配字符 |
參考示例
#輸出除之外的所有行 -v 選項
grep -v "match_pattern" file_name#標記匹配顏色 --color=auto 選項
grep "match_pattern" file_name --color=auto#使用正則表達式 -E 選項:
grep -E "[1-9]+"
egrep "[1-9]+"#選項 -e 制動多個匹配樣式:
echo this is a text line | grep -e "is" -e "line" -o
is
is
line#在多級目錄中對文本進行遞歸搜索:
grep "text" . -r -n
# .表示當前目錄。#忽略匹配樣式中的字符大小寫:
echo "hello world" | grep -i "HELLO"
# hello
四、awk
awk命令來自三位創始人Alfred Aho、Peter Weinberger、Brian Kernighan的姓氏縮寫,用于在linux/unix下對文本和數據進行處理。數據可以來自標準輸入(stdin)、一個或多個文件,或其它命令的輸出。
它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。它在命令行中使用,但更多是作為腳本來使用。awk有很多內建的功能,比如數組、函數等,這是它和C語言的相同之處,靈活性是awk最大的優勢。
語法格式:awk [選項] -f '腳本'/腳本文件 '模式{處理動作}'
4.1、常用命令選項
- -F fs?fs指定輸入分隔符,fs可以是字符串或正則表達式,如-F:,默認的分隔符是連續的空格或制表符
- -v var=value?賦值一個用戶定義變量,將外部變量傳遞給awk
- -f scripfile?從腳本文件中讀取awk命令
- -m[fr] val?對val值設置內在限制,-mf選項限制分配給val的最大塊數目;-mr選項限制記錄的最大數目。這兩個功能是Bell實驗室版awk的擴展功能,在標準awk中不適用。
4.2、工作原理
- 第一步:執行 BEGIN {commands} 語句塊中的語句;
- 第二步:從文件或標準輸入(stdin)讀取一行,然后執行 pattern {commands} 語句塊,它逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢。
- 第三步:當讀至輸入流末尾時,執行 END {commands} 語句塊。
BEGIN語句塊:在awk開始從輸入流中讀取行?之前?被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中。
END語句塊:在awk從輸入流中讀取完所有的行?之后?即被執行,比如打印所有行的分析結果這類信息匯總都是在END語句塊中完成,它也是一個可選語句塊。
pattern語句塊:中的通用命令是最重要的部分,它也是可選的。如果沒有提供pattern語句塊,則默認執行{print},即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊。
?4.3、基礎用法
awk '模式{處理動作}'
#BGEIN{}模式
[root@localhost ~]# awk '{print}'
1
1
aabb
aabb
^C
[root@localhost ~]# awk '{print "aabb"}'
1
aabb#提取磁盤的分區利用率
[root@localhost ~]# df |awk '{print $5}'
已用%
0%
0%
2%
0%
80%
19%
1%
80%
0%#提取用戶名和uid號
[root@localhost ~]# cat /etc/passwd |awk -F: '{print $1,$3}'
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
..............#提取ip地址
[root@localhost ~]# ifconfig ens33 |awk 'NR==2{print $2}'
192.168.153.23
4.4、內置變量
變量 | 定義 |
FS | 字段分隔符(默認空格) |
OFS | 輸出字段分隔符(默認空格) |
NF | 字段數,執行過程中對應當前字段數 |
NR | 記錄數,執行過程中對應當前行號 |
$0 | 當前處理的行的整行內容 |
$n | 當前處理行的第n個字段/列 |
FILENAME | 當前輸入的文件名 |
RS | 記錄分隔符(默認一個換行符) |
參考示例
#FS變量的使用,-F優先級高于FS變量
[root@localhost ~]# awk -v "FS=:" '{print $1FS$3}' /etc/passwd
root:0
bin:1
daemon:2
[root@localhost ~]# awk -F: '{print $1":"$3}' /etc/passwd
root:0
bin:1
daemon:2#OFS變量的使用,替換分隔符
[root@localhost ~]# cat /etc/passwd|awk -v "OFS=--" -F: '{print $1,$3}'|head -n3
root--0
bin--1
daemon--2
[root@localhost ~]# cat /etc/passwd|awk -v "OFS=--" -v "FS=:" '{print $1,$3}'|head -n3
root--0
bin--1
daemon--2#RS變量的使用,替換分隔符為換行符
[root@localhost ~]# echo $PATH|awk -v "RS=:" '{print}'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin#NF變量的使用,顯示最后一列
[root@localhost ~]# df |awk '{print $NF}'
掛載點
/dev
/dev/shm
/run
/sys/fs/cgroup
/
/boot
/run/user/42
/var/lib/docker/overlay2/b3191762ed94dc8a583e6da75d8db197b583d63c7f925833df49e5b51e865a4f/merged
/run/user/0
[root@localhost ~]# df |awk '{print $(NF-1)}'
已用%
0%
0%
2%
0%
80%
19%
1%
80%
0%#NR變量的使用,匹配對應行
[root@localhost ~]# cat /etc/passwd |head -n3|awk '{print NR,$0}'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]# cat /etc/passwd|awk 'NR==1,NR==3{print NR,$0}'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]# cat /etc/passwd|head -n8|awk '(NR%2)==0{print NR,$0}'
2 bin:x:1:1:bin:/bin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
8 halt:x:7:0:halt:/sbin:/sbin/halt
4.5、模式
awk [選項] '模式{處理動作}'
#/正則表達式/:使用通配符的擴展集。
#匹配從root開頭,ftp結尾的行
[root@localhost ~]# awk -F: '/^root/,/^ftp/{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
#僅匹配root開頭,ftp開頭的行
[root@localhost ~]# awk -F: '/^root/||/^ftp/{print $1,$3}' /etc/passwd
root 0
ftp 14
#關系表達式,使用運算符進行操作,可以是字符串或數字的比較測試
#n++表示不匹配第一行,即NR!=1
[root@localhost ~]# ss -natp|awk 'n++{print $1}'|sort|uniq -c1 ESTAB12 LISTEN
[root@localhost ~]# ss -natp|awk 'n++{a[$1]++}END{for(i in a){print a[i],i}}'
12 LISTEN
1 ESTAB[root@localhost ~]# seq 4|awk 'i=!i'
1
3
[root@localhost ~]# seq 4|awk '!(i=!i)'
2
4
[root@localhost ~]# seq 4|awk -v i=1 'i=!i'
2
4
4.6、條件判斷
awk ?選項 ? '模式 {條件|執行動作}'?
#過濾用戶名及uid
[root@localhost ~]# cat /etc/passwd|awk -F: '{if($3>1000)print $1,$3}'
nfsnobody 65534
[root@localhost ~]# cat /etc/passwd|awk -F: '$3>1000{print $1,$3}'
nfsnobody 65534
[root@localhost ~]# cat /etc/passwd|awk -F: '{if($3>=uid){uid=$3;user=$1;sh=$NF}}END{print user,uid,sh}'
nfsnobody 65534 /sbin/nologin
4.7、awk中的循環語句
#for循環
#for(變量;條件;表達式){語句}
[root@localhost ~]# awk 'BEGIN{total=0;for(i=0;i<=100;i++){total+=i;}print total;}'
5050
4.8、數組
數組是awk的靈魂,處理文本中最不能少的就是它的數組處理。因為數組索引(下標)可以是數字和字符串在awk中數組叫做關聯數組(associative arrays)。awk 中的數組不必提前聲明,也不必聲明大小。數組元素用0或空字符串來初始化,這根據上下文而定。
#得到數組長度
#length返回字符串以及數組長度,split進行分割字符串為數組,也會返回分割得到數組長度
[root@localhost ~]# awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),lens;}'
4 4#輸出數組內容
#無序輸出
[root@localhost ~]# awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
4 test
1 it
2 is
3 a
#有序輸出
[root@localhost ~]# awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}'
1 it
2 is
3 a
4 test
4.9、腳本
-f scripfile?從腳本文件中讀取awk命令
[root@localhost opt]# vim asdf.txt
{if($3>=1000)print $1,$3}
[root@localhost opt]# awk -F: -f asdf.txt /etc/passwd
nfsnobody 65534
123123 1000
五、sed
stream editor的縮寫,其功能是利用語法/腳本對文本文件進行批量的編輯操作。
它是文本處理中非常重要的工具,能夠完美的配合正則表達式使用,功能不同凡響。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接著用sed命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。
接著處理下一行,這樣不斷重復,直到文件末尾。文件內容并沒有 改變,除非你使用重定向存儲輸出。
Sed主要用來自動編輯一個或多個文件;簡化對文件的反復操作;編寫轉換程序等。
語法格式:sed [選項] '命令' 文件名
常用參數:
-n | 就顯示腳本處理后的結果 |
-e | 使用指定腳本處理輸入的文本文件 |
-f | 使用指定腳本文件處理輸入的文本文件 |
-r/-E | 支持擴展正則表達式 |
-i.bak | 直接修改文件內容而不輸出到終端,并備份文件 |
[root@localhost opt]# sed -n -e '/^r/p' -e'/^b/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin[root@localhost opt]# sed -i.bak '1,4d' aaa #刪除第1,第4行
[root@localhost opt]# cat aaa
eeeee
fffff
ggggg
hhhhh
[root@localhost opt]# cat aaa.bak
aaaaa
bbbbb
ccccc
ddddd
eeeee
fffff
ggggg
hhhhh
5.1、sed腳本格式
#范圍匹配
[root@localhost opt]# seq 5|sed -n 'p' #不指定范圍則打印全文
1
2
3
4
5
[root@localhost opt]# seq 5|sed -n '3p' #打印第3行
3
[root@localhost opt]# seq 5|sed -n '1,3p' #打印第1,第3行
1
2
3
[root@localhost opt]# seq 5|sed -n '1,+2p' #打印第1行及后2行
1
2
3
[root@localhost opt]# seq 5|sed -n '1,2!p' #取反
3
4
5
#步進
#打印第一行起,后每步進2打印一行,即奇數行
[root@localhost opt]# seq 10|sed -n '1~2p'
1
3
5
7
9
#打印第二行起,后每步進2打印一行,即偶數行
[root@localhost opt]# seq 10|sed -n '2~2p'
2
4
6
8
10
#第二行起,每三行步進打印
[root@localhost opt]# seq 10|sed -n '2~3p'
2
5
8
#第三行起,每三行步進打印
[root@localhost opt]# seq 10|sed -n '3~3p'
3
6
9
?5.2、sed命令
p | 打印模板塊的行 |
q | 退出Sed |
s | 替換指定字符 |
d | 刪除,刪除選擇的行 |
a | 在當前行下面插入文本 |
i | 在指定行上面插入文本 |
c | 把選定的行改為新的文本 |
y | 把一個字符翻譯為另外的字符 |
= | 打印當前行號 |
r | 從file中讀行 |
w | 寫并追加模板塊到file末尾 |
! | 取反 |
#打印到第三行退出
[root@localhost ~]# cat /etc/passwd|sed '3q'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin#指定行后插入
[root@localhost ~]# seq 5|sed '2alook'
1
2
look
3
4
5
[root@localhost ~]# seq 5|sed '4alook\n eyes'
1
2
3
4
lookeyes
5
[root@localhost ~]# seq 5|sed '4alook\neyes'
1
2
3
4
look
eyes
5
[root@localhost ~]# seq 5|sed '3a look'
1
2
3
look
4
5
[root@localhost ~]# seq 5|sed '3a\ look'
1
2
3look
4
5#指定行前插入
[root@localhost ~]# seq 5|sed '3i\ look'
1
2look
3
4
5
[root@localhost ~]# seq 5|sed '4ilook\neyes'
1
2
3
look
eyes
4
5#替換行
[root@localhost ~]# seq 5|sed '3c\ look'
1
2look
4
5
[root@localhost ~]# seq 5|sed '4clook\neyes'
1
2
3
look
eyes
5
5.3、搜索替換
替換標記 | 定義 |
g | 行內全面替換 |
p | 打印行 |
w | 把行寫入一個文件 |
x | 互換模板塊中的文本和緩沖區中的文本 |
y | 把一個字符翻譯為另外的字符 |
\1 | 子串匹配標記 |
& | 已匹配字符串標記 |
基本格式 s/pattern/string/修飾符
#替換第二個.為@
[root@localhost opt]# sed 's/\./@/2' /etc/hosts
127.0@0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6@localdomain6#匹配字符后添加
[root@localhost opt]# sed -n 's/r..t/&er/gp' /etc/passwd
rooter:x:0:0:rooter:/rooter:/bin/bash
operator:x:11:0:operator:/rooter:/sbin/nologin
ftp:x:14:50:FTP User:/var/fterp:/sbin/nologin
5.4、分組后向引用
#提取ip地址
[root@localhost opt]# ifconfig ens33|sed -rn '2s/.*inet ([0-9.]+) .*/\1/p'
192.168.153.23#提取文件權限
[root@localhost opt]# stat aaa文件:"aaa"大小:24 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:18799731 硬鏈接:1
權限:(0644/-rw-r--r--) Uid:( 0/ root) Gid:( 0/ root)
環境:unconfined_u:object_r:usr_t:s0
最近訪問:2025-05-02 21:53:35.697373969 +0800
最近更改:2025-05-02 21:53:24.391268086 +0800
最近改動:2025-05-02 21:53:24.391268086 +0800
創建時間:-
[root@localhost opt]# stat aaa |sed -nr '4s/.*([0-9]{4}).*/\1/p'
0644
[root@localhost opt]# stat aaa|sed -n '4p'|egrep -o "[0-9]{4}"
0644
[root@localhost opt]# stat aaa|awk -F"[(/]" 'NR==4{print $2}'
0644