Linux正则与文本处理工具
正則表達式 (Regular Expression, RE, 或稱為常規表達式)是通過一些特殊字符的排列,用于『查找/替換/刪除』一行或多行文字或字符串,簡單的說,正則表達式就是用在字串的處理上面的一種『表示公式』,正則表達式并不是一個工具程序,而是一個對字符串處理的標準依據,如果您想要以正則表達式的方式處理字串,就得要使用支持正則表達式的工具程序才行,這類的工具程序很多,例如 vi,vim,sed,awk,gawk,egrep等.
正則表達式,對于系統管理員來說是非常重要的,因為系統會產生很多的信息,這些信息有的重要有的僅是警告,此時管理員可以通過正則表達式來過濾出相應的我們需要的字段,你最好掌握這門技術,會對將來的數據分析,主機管理起到很大的幫助.
基礎正則表達式
在上一章說過正則表達式和通配符的區別,(正則表達式用來在文件中匹配符合條件的字符串,而通配符則是用來匹配符合條件的文件名)嗎? 其實這種區別只在Shell當中適用,因為用來在文件當中搜索字符串的命令,如 grep、awk、sed 等命令可以支持正則表達式,而在系統當中搜索文件的命令,如 ls、find、cp 這些命令不支持正則表達式,所以只能使用shell自己的通配符來進行匹配了.
首先我們先來學習一下基礎的正則表達式吧,下面是我們常用的正則語法,我會給每一個語法,舉一個小例子,下面我們開始學習吧.
實例1: 使用 * 實現匹配前一個字符出現0次或任意多次(本例中,則是匹配g字符出現0次或任意多次)
[root@localhost ~]# ls wang wangg wanggg[root@localhost ~]# ls | grep "wang*" wang wangg wanggg [root@localhost ~]# ls | grep "wan*g*" wang wangg wanggg實例2: 使用 . 實現匹配除換行符以外的任意一個字符,(只匹配一個字符),一般我們把它叫做貪婪匹配
[root@localhost ~]# ls wang wangg wanggg wangr[root@localhost ~]# ls | grep "wang" wang [root@localhost ~]# ls | grep "wang." wangg wangr [root@localhost ~]# ls | grep "wang.." wanggg實例3: 使用 ^ 實現匹配行首是指定字符的行
[root@localhost ~]# ls alert lyshark tcpl wakaka wang wangg wanggg woxin[root@localhost ~]# ls | grep "^ly" lyshark [root@localhost ~]# ls | grep "^wa" wakaka wang wangg wanggg [root@localhost ~]# ls | grep "^a" alert實例4: 使用 $ 實現匹配行尾是指定字符的行
[root@localhost ~]# ls alert lyshark tcpl wakaka wang wangg wanggg woxin[root@localhost ~]# ls | grep "a$" wakaka [root@localhost ~]# ls | grep "ark$" lyshark [root@localhost ~]# ls | grep "^w" | grep "n$" #匹配開頭是w結尾是n的 woxin實例5: 使用 [] 實現匹配中括號內任意一個字符,(只匹配其中一個)
[root@localhost ~]# ls ale1t ale2t ale3t aleat alebt alert[root@localhost ~]# ls | grep "ale[a-z]t" aleat alebt alert [root@localhost ~]# ls | grep "ale[0-9]t" ale1t ale2t ale3t [root@localhost ~]# ls | grep "ale[ab]t" aleat alebt實例6: 使用 [^] 實現匹配除了中括號字符以外的任意一個字符(^取反的意思)
[root@localhost ~]# ls ale1t ale2t ale3t aleat aleAt aleBB alebt aleCT aleEt alert[root@localhost ~]# ls | grep "ale[^0-9]t" aleat aleAt alebt aleEt alert [root@localhost ~]# ls | grep "ale[^A-Z]t" ale1t ale2t ale3t aleat alebt alert [root@localhost ~]# ls | grep "ale[^AE]t" ale1t ale2t ale3t aleat alebt alert實例7: 使用 ^[^] 實現匹配行首是與不是指定字符的行
[root@localhost ~]# ls ale1t ale2t lyshark tcpl wakaka wang wangg wanggg woxin[root@localhost ~]# ls | grep ^[a] #匹配行首是a開頭的 ale1t ale2t [root@localhost ~]# ls | grep ^[^a] #匹配行首不是a開頭的 lyshark tcpl wakaka wang wangg wanggg woxin實例8: 使用 \{n}\ 實現匹配前面的字符恰好出現了n次的行
[root@localhost ~]# ls 12333 13466614578 13562653874 172.168.1.2 18264758942 192.168.1.1 45666 78999[root@localhost ~]# ls | grep "123\{3\}" 12333 [root@localhost ~]# ls | grep "[0-9][0-9][0-9]\{3\}" #匹配前兩個字符是0-9的,最后一個字符出現過3次的 12333 45666 78999 [root@localhost ~]# ls | grep "[1][3-8][0-9]\{9\}" #匹配手機號規則 13466614578 13562653874 18264758942實例9: \{n,}\ 實現匹配前面的字符的出現,不小于n次的行
[root@localhost ~]# ls 12333 123333 1233333[root@localhost ~]# ls | grep "123\{3,\}" #前一個字符3的出現不小于3次 12333 123333 1233333 [root@localhost ~]# ls | grep "123\{4,\}" #前一個字符3的出現不小于4次 123333 1233333實例10: \{n,m}\ 實現匹配前面的字符出現,不小于n次,最多出現m次的行
[root@localhost ~]# ls 123 1233 12333 123333 1233333 12333333 123333333 1233333333 12333333333[root@localhost ~]# ls |grep "123\{3,5\}" #前一個字符3最少出現3次,最多不大于5次 12333 123333 1233333總結:匹配一個合法IP地址
[root@localhost ~]# ls 10.10.10.22 127.9.0.8 172.168.1.2 192.168.1.1 192.168.1.3 255.255.255.255 127.0.0.1 172.168.1.1 172.168.1.3 192.168.1.2 192.199.256.256 256.256.256.256[root@localhost ~]# ls | egrep "^(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]| 2[0-4][0-9]|25[0-4])$"10.10.10.22 172.168.1.1 172.168.1.2 172.168.1.3 192.168.1.1 192.168.1.2 192.168.1.3總結:匹配一個合法郵箱地址
[root@localhost ~]# ls 1181506874@qq.com lysharks@163.cn lysharks@163.com wangrui@126.com wangrui@129.cc[root@localhost ~]# ls | egrep "^[0-9a-zA-Z][0-9a-zA-Z_]{1,16}[0-9a-zA-Z]\@[0-9a-zA-Z-]*([0-9a-zA-Z])?\.(com|com.cn|net| org|cn)$"1181506874@qq.com lysharks@163.cn lysharks@163.com wangrui@126.com擴展正則表達式
事實上,一般用戶只要了解基礎型的正則語句就已經相當足夠了,不過,在某些時候,為了簡化命令的長度,還是需要擴展正則的支持的,打個比方,我們可以使用 cat xxx.log | grep -v '^$' |grep -v '^#' 來實現過濾文本中的注釋行,和空白行,但是這不夠精簡,它的執行還是會用到兩次的過濾,如果使用擴展正則表達式,我們可以這樣寫,cat xxx.log |egrep -v '^$|^#' 這樣一個命令就可實現上面的效果啦,此處我們需要說明的是,grep -E 和egrep效果是相同的,使用哪一個都一個樣.
熟悉了基礎正規表達式之后,再來看這個擴展正則表達式,是不是很輕松啊,親,下面我們就來分別說明這幾個符號的使用規則吧.
實例1: + 實現匹配前一個字符出現1次或任意多次
[root@localhost ~]# ls gogle google gooogle gooogooogle goooogle gooooogle goooooogle[root@localhost ~]# ls | grep -E "go+gle" gogle google gooogle goooogle gooooogle goooooogle實例2: ? 實現匹配前一個字符出現0次,或1次
[root@localhost ~]# ls gogle google gooogle gooogooogle goooogle gooooogle goooooogle[root@localhost ~]# ls | grep -E "go?gle" gogle [root@localhost ~]# ls | grep -E "goo?gle" gogle google實例3: | 實現匹配兩個或多個分支選擇
[root@localhost ~]# ls alert lyshark rui wang[root@localhost ~]# ls | grep -E "alert|lyshark" alert lyshark [root@localhost ~]# ls | grep -E "wang|rui|alert" alert rui wang實例4: () 實現將字符作為一個整體匹配,即模式單元
[root@localhost ~]# ls dog dogdog dogdogdog hello_lyshark hello_world[root@localhost ~]# ls | grep -E "(dog)+" dog dogdog dogdogdog [root@localhost ~]# ls | grep -E "hello_(world|lyshark)" hello_lyshark hello_worldGrep 行處理工具
grep (global search regular expression(RE) and print out the line 全面搜索正則表達式并把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,并把匹配的行打印出來,好了廢話不多說,先看命令格式.
[root@localhost ~]# grep --help命令語法:[ grep [選項] [過濾菜單] 文件名 ]-a #將二進制數據一同列出-c #計算找到查找字符串的次數-i #忽略大小寫差異-n #順便標號顯示-v #反選參數-q #不顯示任何提示信息,安靜模式-E #使用擴展正則,egrep-A #匹配指定字符的后n個字符-B #匹配指定字符的前n個字符-C #匹配指定字符的前n個和后n個字符實例1: 使用 grep -n 參數過濾數據時,一同標號
[root@localhost ~]# cat /etc/passwd | grep -n "root"1:root:x:0:0:root:/root:/bin/bash 10:operator:x:11:0:operator:/root:/sbin/nologin實例2: 使用 grep -v 反選打印,行中不包括/bin/bash的行
[root@localhost ~]# cat /etc/passwd | grep -vn "/bin/bash"2:bin:x:1:1:bin:/bin:/sbin/nologin 3:daemon:x:2:2:daemon:/sbin:/sbin/nologin 4:adm:x:3:4:adm:/var/adm:/sbin/nologin 5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6:sync:x:5:0:sync:/sbin:/bin/sync 7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8:halt:x:7:0:halt:/sbin:/sbin/halt ....省略....實例3: 使用 grep -i 過濾出不論大小寫的lyshark單詞的行
[root@localhost ~]# cat lyshark.log LyShark lyshark admin Admin ADMIN Good GOOD[root@localhost ~]# cat lyshark.log | grep -ni "lyshark" 1:LyShark 2:lyshark實例4: 使用正則,過濾出開頭是 ^L 的行的內容
[root@localhost ~]# cat lyshark.log LyShark lyshark admin Admin ADMIN Good GOOD[root@localhost ~]# cat lyshark.log | grep -n "^L" 1:LyShark實例5: 使用正則,過濾出開頭不是 ^L的行的內容
[root@localhost ~]# cat lyshark.log LyShark lyshark admin Admin ADMIN Good GOOD[root@localhost ~]# cat lyshark.log | grep -n "[^L]yshark" 2:lyshark實例6: 使用正則,過濾出開頭是小寫字母的行
[root@localhost ~]# cat lyshark.log LyShark lyshark admin Admin ADMIN Good GOOD 123123 1233 66431 124adb[root@localhost ~]# cat lyshark.log | grep -n "^[a-z]" 2:lyshark 3:admin實例7: 使用正則,過濾出開頭不是,a-z或A-Z的行
[root@localhost ~]# cat lyshark.log LyShark lyshark admin Admin ADMIN Good GOOD 123123 1233 66431 124adb[root@localhost ~]# cat lyshark.log | grep -n "^[^a-zA-Z]" 8:123123 9:1233 10:66431 11:124adb實例8: 使用正則,找出結尾是小數點的哪一行
[root@localhost ~]# cat lyshark.log LyShark lyshark admin Admin ADMIN Good 123123 1233. 66431.[root@localhost ~]# cat lyshark.log |grep -n "\.$" 8:1233. 9:66431.實例9: 使用正則,過濾掉開頭是#號的,和開頭是空行的行
[root@localhost ~]# cat lyshark.log #LyShark #lyshark #admin #AdminADMIN Good1231231233. 66431.[root@localhost ~]# cat lyshark.log | grep -v "^#" | grep -v "^$" ADMIN Good 123123 1233. 66431.實例10: 使用正則,過濾出前一個字符o剛好出現兩次的行
[root@localhost ~]# cat lyshark.log #LyShark #lyshark #admin #AdminADMIN Good 123123 1233. 66431.[root@localhost ~]# cat lyshark.log |grep -n "o\{2\}" 7:Good實例11: 使用正則,匹配開頭是0-9且結尾是點的行
[root@localhost ~]# cat lyshark.log #LyShark #lyshark #admin #AdminADMIN Good 123123 1233. 66431.[root@localhost ~]# cat lyshark.log |grep -n -E "^[0-9]+\." 9:1233. 10:66431.實例12: 使用正則,匹配指定字符的后2個字符,或前2個字符
[root@localhost ~]# cat lyshark.log lyshark LySHARK wang rui hello world alert 123123 45678[root@localhost ~]# cat lyshark.log |grep -n -A 2 "hello" 5:hello 6-world 7-alert[root@localhost ~]# cat lyshark.log |grep -n -B 2 "hello" 3-wang 4-rui 5:helloCut 列提取工具
cut命令用來顯示行中的指定部分,刪除文件中指定字段,cut經常用來顯示文件的內容,類似于type命令.該命令有兩項功能,其一是用來顯示文件的內容,它依次讀取由參數file所指明的文件,將它們的內容輸出到標準輸出上.其二是連接兩個或多個文件,如cut fl f2 > f3 將把文件fl和f2的內容合并,然后通過輸出重定向符">" 的作用,將它們放入文件f3中.
首先我們來看一下它的格式吧,如下:
[root@localhost ~]# cut --help命令語法:[ cut [選項] [列號] 文件名 ]-f #-f 列號:指定提取第幾列-d #-d 分隔符:按照指定分隔符進行分割-c #-c 字符范圍:不依賴分割符來分割,而是通過字符范圍進行字段提取-m #表示從第一個字符提取到第m個-b #僅顯示行中指定直接范圍的內容-n #與"-b"選項連用,不分割多字節字符n- #表示從第n個字符開始提取到結尾n-m #表示從第n提取到第m個字符--complement #補齊被選擇的字節,字符或字段--out-delimiter=<字段分隔符> #指定輸出內容是的字段分割符手動創建一個文本,添加內容列之間用tab分隔,用來測試后續內容
[root@localhost ~]# cat lyshark.logID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88實例1: 通過使用 -f 選項指定過濾的列,并顯示到屏幕
[root@localhost ~]# cat lyshark.logID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88[root@localhost ~]# cut -f 2 lyshark.log NAME WR LC LY[root@localhost ~]# cut -f 2,5 lyshark.log NAME Mark WR 100 LC 90 LY 88實例2: 通過使用 --complement 選項提取指定字段之外的列,(打印除了第2列之外的列)
[root@localhost ~]# cat lyshark.logID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88[root@localhost ~]# cut -f 2 --complement lyshark.logID AGE Gender Mark 1 22 m 100 2 26 m 90 3 23 m 88實例3: 通過使用 -c 選項過濾/etc/passwd,并打印第1個到第3個字符
[root@localhost ~]# cut -c 1-3 /etc/passwd roo bin dae adm lp: syn ....省略....實例4: 通過使用 -c -2 選項過濾/etc/passwd,并打印前2個字符
[root@localhost ~]# cut -c -2 /etc/passwd ro bi da ad lp ....省略....實例5: 通過使用 -c 5- 選項過濾/etc/passwd,打印從第5個字符開始到結尾
[root@localhost ~]# cut -c 5- /etc/passwd :x:0:0:root:/root:/bin/bash x:1:1:bin:/bin:/sbin/nologin on:x:2:2:daemon:/sbin:/sbin/nologin x:3:4:adm:/var/adm:/sbin/nologin ....省略....實例6: 通過使用 -d 指定分隔符 -f 指定打印第個字段,以下我們分別截取第1和第7個字段
[root@localhost ~]# cut -d ":" -f 1,7 /etc/passwd root:/bin/bash bin:/sbin/nologin daemon:/sbin/nologin adm:/sbin/nologin lp:/sbin/nologin sync:/bin/sync ....省略....實例7: 通過使用 -c -3 指定截取前3個字符,還可以通過 -c 3 截取第3個字符
[root@localhost ~]# cut -c -3 /etc/passwd roo bin dae adm lp: ....省略.... [root@localhost ~]# cut -c 3 /etc/passwd o n e m : n ....省略....Sed 流編輯器
sed是一種流編輯器,它是文本處理中非常中的工具,能夠完美的配合正則表達式使用,功能不同凡響.處理時,把當前處理的行存儲在臨時緩沖區中,稱為 "模式空間" (pattern space),接著用sed命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕,接著處理下一行,這樣不斷重復,直到文件末尾.文件內容并沒有改變,除非你使用重定向存儲輸出.Sed主要用來自動編輯一個或多個文件,簡化對文件的反復操作,編寫轉換程序等.
sed主要是來進行數據選取,替換,刪除,新增的命令,二話不說先看一下它的參數吧.
[root@localhost ~]# sed --help命令語法:[ sed [選項] [范圍] [動作] 文件名 ]-n #把經過sed命令處理的行輸出到屏幕-e #允許對輸入數據應用多條sed命令編輯-f #從sed腳本中讀入sed操作,和awk命令的-f類似-r #在sed中支持擴展正則表達式-i #用sed的修改結果,寫到文件命令動作:p #打印,輸出指定的行a #追加,在當前行后添加一行或多行i #插入,在當前行前插入一行或多行c #整行替換,用c后面的字符串替換原數據行d #刪除,刪除指定的行s #字串替換,格式:"行范圍s/舊字串/新字串/g"#對sed命令我們要知道的是,它所有的修改都不會直接修改文件的內容,而是在內存中進行處理然后打印到屏幕上 #如果想要寫入文件,請使用 sed -i 選項才會保存到文本中.在進行實驗之前,首先創建一個文件,來做測試用
[root@localhost ~]# cat lyshark.logID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100實例1: 使用 sed '2p' 重復打印第二行數據
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed '2p' lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 1 WR 22 m 100 ←本行是2p打印的 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed '3p' lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 2 LC 26 m 90 ←本行是2p打印的 3 LY 23 m 88 4 XDL 40 b 100實例2: 使用 sed -n 限定,只選取指定的行進行顯示
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed -n '2p' lyshark.log ←只打印第2行數據 1 WR 22 m 100[root@localhost ~]# sed -n '1p' lyshark.log ←只打印第1行數據 ID NAME AGE Gender Mark實例3: 使用 sed '2,4d' 刪除掉文件2-4行,并顯示到屏幕,(原文件內容并沒有被修改)
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed '2,4d' lyshark.log ←刪除2-4行的數據并打印 ID NAME AGE Gender Mark 4 XDL 40 b 100[root@localhost ~]# sed '1d' lyshark.log ←刪除第1行的數據 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100實例4: 使用 sed '2[a|i]' 追加,或者插入數據指定數據
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed '2a hello lyshark' lyshark.log ←在第2行后面追加數據 ID NAME AGE Gender Mark 1 WR 22 m 100 hello lyshark 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed '2i hello lyshark' lyshark.log ←在第2行前面插入數據 ID NAME AGE Gender Mark hello lyshark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100實例5: 使用 \ 換行符,一次插入多行數據
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed '2a hello \ ←在第二行下面,插入一段話,用\隔開 > my name is lyshark \ > age 22 \ > boy ' lyshark.logID NAME AGE Gender Mark 1 WR 22 m 100 hello my name is lyshark age 22 boy 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100實例6: 使用 sed 'c' 實現整行替換數據
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# cat lyshark.log | sed '5c 5 WRS 99 m 111' ←整行替換第5行內容 ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 5 WRS 99 m 111實例7: 使用 sed 后面跟上 -i 選項,將第5行的修改,保存進文件,(-i選項是回寫)
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# sed -i '5c 5 WRS 99 m 111' lyshark.log[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 5 WRS 99 m 111 ←這里的數據已經寫入成功實例8: 字符串的替換 sed 's/舊文本/新文本/g' 進行整行替換
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 5 WRS 99 m 111[root@localhost ~]# sed '2s/WR/LyShark/g' lyshark.log ←將第2行的,WR替換成LyShark ID NAME AGE Gender Mark 1 LyShark 22 m 100 2 LC 26 m 90 3 LY 23 m 88 5 WRS 99 m 111[root@localhost ~]# sed '3s/LC/Admin/g' lyshark.log ←將第3行的,LC替換成Admin ID NAME AGE Gender Mark 1 WR 22 m 100 2 Admin 26 m 90 3 LY 23 m 88 5 WRS 99 m 111#注意:上方只是替換打印,并沒有保存,如若想保存請加 -i 屬性實例9: 將第3行數據的開頭添加#注釋
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 5 WRS 99 m 111[root@localhost ~]# sed '3s/^/#/g' lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 #2 LC 26 m 90 3 LY 23 m 88 5 WRS 99 m 111實例10: 將第4和第5行的內容替換成空
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 5 WRS 99 m 111[root@localhost ~]# sed -e '4s/LY//g ; 5s/WRS//g' lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 23 m 88 5 99 m 111#sed 要進行多行操作時,只能通過 -e 寫多條操作語句,用 ; 或回車分隔過濾IP地址小實驗
[root@localhost ~]# ifconfig ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.1.10 netmask 255.255.255.0 broadcast 192.168.1.255inet6 fe80::897c:d72d:cd95:b9ec prefixlen 64 scopeid 0x20<link>ether 00:0c:29:b1:b7:be txqueuelen 1000 (Ethernet)RX packets 2344 bytes 156370 (152.7 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 454 bytes 50049 (48.8 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@localhost ~]# ifconfig | grep "inet 192" |sed 's/^.*inet //g' 192.168.1.10 netmask 255.255.255.0 broadcast 192.168.1.255[root@localhost ~]# ifconfig |grep "inet 192" |sed 's/^.*inet //g' |sed 's/ netmask.*$//g' 192.168.1.10Printf 文本格式化
[root@localhost ~]# printf --help輸出類型:%ns: #輸出字符串,n是數字,指代輸出幾個字符%ni: #輸出證書,n是數字,指代輸出幾個數字%m.nf: #輸出浮點數,m和n是數字,指代輸出整數位和小數位輸出格式:\a: #輸出警告音\b: #輸出退格鍵,也就是Backspace鍵\f: #清屏\n: #換行符\r: #回車,也就是Enter鍵\t: #水平輸出退格鍵,也就是Tab鍵\v: #垂直輸出退格鍵,也就是Tab鍵#注意:print 和 printf 的主要區別在有 printf 是標準的格式化輸出,必須手動指定換行和tab.在進行實驗之前,首先創建一個文件,來做測試用
[root@localhost ~]# cat lyshark.logID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100實例1: 通過 printf 函數打印文本內容
printf命令,如果不指定輸出格式,則會把所有輸出內容連在一起輸出,其實文本的輸出本身就是這樣的,cat等文本輸出命令之所以可以按照格式漂亮的輸出,那是因為cat命令已經設定了輸出格式.
[root@localhost ~]# printf '%s' $(cat lyshark.log)IDNAMEAGEGenderMark1WR22m1002LC26m903LY23m884XDL40b100實例2: 通過 printf 格式化后輸出一段文本
[root@localhost ~]# printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat lyshark.log)ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100實例3: 通過 printf 按照整數型和浮點型輸出,則需要修改
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# printf '%i\t %s\t %8.2f\t %s\t %s\t \n' $(cat lyshark.log |grep -v ID) 1 WR 22.00 m 100 2 LC 26.00 m 90 3 LY 23.00 m 88 4 XDL 40.00 b 100## Awk 正則表達工具
awk是一種編程語言,用于在linux/unix下對文本和數據進行處理,數據可以來自標準輸入(stdin),一個或多個文件,或其它命令的輸出.它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具,它在命令行中使用,但更多是作為腳本來使用.awk有很多內建的功能,比如數組、函數等,這是它和C語言的相同之處,靈活性是awk最大的優勢.
在開始看例子之前,老樣子,你懂的
[root@localhost ~]# awk --help Usage: awk [POSIX or GNU style options] -f progfile [--] file ... Usage: awk [POSIX or GNU style options] [--] 'program' file ...命令語法:[ awk '條件1{動作1} 條件2{動作2} ....' 文件名 ]條件:一般使用關系表達式作為條件x>10 判斷x變量是否大于10x==y 判斷變量x是否等于變量yA ~ B 判斷字符串A中是否包含能匹配B表達式的字符串A!~ B 判斷字符串A中是否不包含能匹配B表達式的字符串在進行實驗之前,首先創建一個文件,來做測試用
[root@localhost ~]# cat lyshark.logID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100◆awk常用例子◆
實例1: 使用awk格式化輸出第二列和第三列的內容
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# awk '{ printf $2 "\t" $3 "\n" }' lyshark.log NAME AGE WR 22 LC 26 LY 23 XDL 40實例2: 通過awk命令截取Size和Used命令的顯示列
[root@localhost ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 8.0G 1.2G 6.9G 15% / devtmpfs 98M 0 98M 0% /dev tmpfs 110M 0 110M 0% /dev/shm tmpfs 110M 5.5M 104M 5% /run tmpfs 110M 0 110M 0% /sys/fs/cgroup /dev/sda1 1014M 130M 885M 13% /boot tmpfs 22M 0 22M 0% /run/user/0[root@localhost ~]# df -h |awk '{ printf $2 "\t" $3 "\n" }' Size Used 8.0G 1.2G 98M 0 110M 0 110M 5.5M 110M 0 1014M 130M 22M 0◆begin 與 end◆
BEGIN是awk的保留字,是一種特殊的條件類型.BEGIN的執行時機是 "在awk程序一開始時,尚未讀取任何數據之前執行",一旦BEGIN后的動作執行一次,當awk開始從文件中讀入數據,BEGIN的條件就不再成立,所以BEGIN定義的動作只能被執行一次,例如:
下面的,整個動作定義了兩個動作,先打印 "執行語句前,執行我" 然后輸出過濾后的2和4列
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# awk 'BEGIN{ printf "執行語句前,執行我 \n" }{ printf $2 "\t" $4 "\n" }' lyshark.log 執行語句前,執行我 NAME Gender WR m LC m LY m XDL bEND也是awk保留字,不過剛好和BEGIN相反,END是在awk程序處理完所有數據,即將結束時執行.END后的動作只在程序結束時執行一次.
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# awk 'END{ printf "執行語句結束后,執行我 \n" }{ printf $2 "\t" $4 "\n" }' lyshark.log NAME Gender WR m LC m LY m XDL b 執行語句結束后,執行我BEGIN與END連用,以下例子也就是實現了,開始前執行打印 "執行語句前,先執行我",結束時執行打印 "執行語句后,在執行我"
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# awk 'BEGIN{ printf "執行語句前,先執行我 \n" }END{ printf "執行語句后,在執行我 \n"}{ printf $2 "\t" $4 "\n" }' lyshark.log執行語句前,先執行我 NAME Gender WR m LC m LY m XDL b 執行語句后,在執行我◆awk關系運算◆
關系運算符:設定條件,符合執行不符合不執行,下面設定條件為AGE字段>=25歲的列出
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# cat lyshark.log | grep -v ID | awk '$3 >=25 {print $1 "\t" $2}' 2 LC 4 XDL◆awk正則搜索◆
awk是列提取命令,第一步的動作卻是先讀入第一行,整個執行步驟:
? 如果有BEGIN條件,則先執行BEGIN定義動作.
? 如果沒有BEGIN條件,則先讀入第一行,把第一行的數據依次賦成$0 $1 $2 $3 …等變量,$0 代表整行數據,$1 則為第一個字段,依次類推.
? 讀入下一行,重復賦值變量,并打印數據.
指定搜索: 正則搜索第2列NAME字段,包含XDL的行,并打印出AGE列對應的值
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# awk '$2 ~/XDL/ {printf $3 "\n"}' lyshark.log 40[root@localhost ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 8.0G 1.2G 6.9G 15% / devtmpfs 98M 0 98M 0% /dev tmpfs 110M 0 110M 0% /dev/shm tmpfs 110M 5.5M 104M 5% /run tmpfs 110M 0 110M 0% /sys/fs/cgroup /dev/sda1 1014M 130M 885M 13% /boot tmpfs 22M 0 22M 0% /run/user/0[root@localhost ~]# df -h | grep -v "Filesystem" | awk ' $1 ~/sda1/ {print $2}' 1014M全局搜索: 正則全局搜索包含WR的字段行,并打印本行
[root@localhost ~]# cat lyshark.log ID NAME AGE Gender Mark 1 WR 22 m 100 2 LC 26 m 90 3 LY 23 m 88 4 XDL 40 b 100[root@localhost ~]# cat lyshark.log | awk '/WR/ {printf $0 "\n"}' 1 WR 22 m 100屏蔽顯示: 查看 df 的真實分區的使用情況,不看光盤和虛擬磁盤
[root@localhost ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 8.0G 1.2G 6.9G 15% / devtmpfs 98M 0 98M 0% /dev tmpfs 110M 0 110M 0% /dev/shm tmpfs 110M 5.5M 104M 5% /run tmpfs 110M 0 110M 0% /sys/fs/cgroup /dev/sda1 1014M 130M 885M 13% /boot tmpfs 22M 0 22M 0% /run/user/0[root@localhost ~]# df -h | awk '/sda[0-9]/ {printf $1 "\t" $5"\n"}' /dev/sda1 13%◆awk內置變量◆
實例1: 通過內置變量 FS=":" 定義分隔符,打印/etc/passwd文件的第1列和第3列
[root@localhost ~]# cat /etc/passwd |grep "/bin/bash" root:x:0:0:root:/root:/bin/bash[root@localhost ~]# cat /etc/passwd |grep "/bin/bash" | \ > awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'root 0實例2: 打印行內容的同時,打印出行號(NR變量),和字段數(NF變量)
[root@localhost ~]# cat /etc/passwd | grep "/bin/bash" | \ awk 'BEGIN{FS=":"} {print $1 "\t" $3 "\t" "行號: " NR "\t" " 字段數: " NF}'root 0 行號: 1 字段數: 7實例3: 打印行內容,首先判斷 $1==sshd 然后再打印本行的行號等信息
[root@localhost ~]# cat /etc/passwd | grep "/sbin/nologin" | \ awk 'BEGIN{FS=":"}$1=="sshd" {print $1 "\t" $3 "\t" "行號 : " NR "\t" "字段數: " NF}'sshd 74 行號: 13 字段數: 7實例4: 一個分區統計的小例子
[root@localhost ~]# df -h |grep -v "Filesystem" | \ awk '$1=="/dev/sda1" {print $1 "\t" $5 "\t" "行號:" NR "\t" "字段數:" NF }'/dev/sda1 13% 行號:6 字段數:6◆awk流程控制◆
在awk編程中,因為命令語句非常長,輸入格式時需要注意以下內容:
? 多個條件{動作}可以用空格分割,也可以用回車分割.
? 在一個動作中,如果需要執行多個命令,需要用";"分割,或用回車分割.
? 在awk中,變量的賦值與調用都不需要加入"$"符.
? 條件中判斷兩個值是否相同,請使用"==",以便和變量賦值進行區分.
實例1: 將第2行,到第4行,的內容加起來,最后輸出結果
[root@localhost ~]# cat lyshark.log ID NAME AGE SEX LINUX 1 LY 18 boy 100 2 SC 30 man 150 3 WR 22 man 90 4 ZSX 55 boy 96[root@localhost ~]# awk 'NR==2{x=$3} NR==3{y=$3} NR==4{z=$3} {totle=x+y+z;print "Totle is:" totle}' lyshark.log Totle is:0 Totle is:18 Totle is:48 Totle is:70 Totle is:70[root@localhost ~]# awk 'NR==2{x=$3} NR==3{y=$3} NR==4{z=$3;totle=x+y+z;print "Totle is:" totle}' lyshark.log Totle is:70實例2: 統計AGE列,將年齡小于25歲的任過濾出來,并顯示 is young man!
[root@localhost ~]# cat lyshark.log ID NAME AGE SEX LINUX 1 LY 18 boy 10 2 SC 30 man 50 3 WR 22 man 90 4 ZSX 55 boy 96[root@localhost ~]# cat lyshark.log | awk '{if (NR >= 2){if ($3 < 25) printf $2 " IS Young Man! \n"}}' LY IS Young Man! WR IS Young Man!實例3: 統計LINUX列,當出現大于80分的,打印到屏幕上 is good man!
[root@localhost ~]# cat lyshark.log ID NAME AGE SEX LINUX 1 LY 18 boy 10 2 SC 30 man 50 3 WR 22 man 90 4 ZSX 55 boy 96[root@localhost ~]# cat lyshark.log | awk 'NR>=2 {temp=$5} temp>80 {printf $2 "IS Good Man!\n"}' WRIS Good Man! ZSXIS Good Man!◆awk函數編寫◆
實例1: 通過定義的函數格式,去匹配并傳遞參數
[root@localhost ~]# cat lyshark.log ID NAME AGE SEX LINUX 1 LY 18 boy 10 2 SC 30 man 50 3 WR 22 man 90 4 ZSX 55 boy 96[root@localhost ~]# cat lyshark.log | awk 'function lyshark(x,y) {printf x "\t" y "\n"}{lyshark($2,$5)}' NAME LINUX LY 10 SC 50 WR 90 ZSX 96實例2: awk中調用腳本,對于小的單行程序來說,將腳本作為命令行自變量傳遞給awk是非常簡單的,而對于多行程序就比較難處理.當程序是多行的時候,使用外部腳本是很適合的.首先在外部文件中寫好腳本,然后可以使用awk的-f選項,使其讀入腳本并且執.
[root@localhost ~]# cat passwd.awk BEGIN {FS=":"} {print $1 "\t" $3}[root@localhost ~]# cat /etc/passwd | awk -f passwd.awk root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 operator 11 games 12 ftp 14 nobody 99 systemd-network 192 dbus 81 polkitd 999 sshd 74 postfix 89 chrony 998## diff/patch 文件比對
什么時候會用到文件的比對啊? 通常是『同一個套裝軟件的不同版本之間,比較配置文件的差異』,很多時候所謂的文件比對,通常是用在 ASCII 純文字檔的比對上的,那么比對文件最常見的就是 diff .
diff命令在最簡單的情況下,比較給定的兩個文件的不同.如果使用 "-" 代替 "文件" 參數,則要比較的內容將來自標準輸入,diff命令是以逐行的方式,比較文本文件的異同處,如果該命令指定進行目錄的比較,則將會比較該目錄中具有相同文件名的文件,而不會對其子目錄文件進行任何比較操作.
◆diff 生成補丁文件◆
[root@localhost ~]# diff --help Usage: diff [OPTION]... FILES Compare FILES line by line.語法格式:[ diff [選項] 源文件 新文件 > *.patch ]-a #將任何文檔當做文本文檔處理-b #忽略空格造成的不同-B #忽略空白行造成的不同-I #忽略大小寫造成的不同-N #當比較目錄時,若某個文件只在一個目錄中,則另一個目錄中視作空文件-r #當比較目錄時,遞歸比較子目錄-u #使用同一的輸出格式----------------------------------------------------------------- 說明: 生成補丁的例子1.首先創建兩個文件,分別寫入以下內容,內容要不同,因為要生成補丁.[root@localhost ~]# cat old hello world[root@localhost ~]# cat new hello worldwelcome to lyshark blog2.利用命令生成補丁文件 *.patch[root@localhost ~]# diff -Naur /root/old /root/new > lyshark.patch[root@localhost ~]# cat lyshark.patch --- /root/old 2018-09-21 05:41:55.487052312 -0400 +++ /root/new 2018-09-21 05:42:10.581184526 -0400 @@ -1 +1,3 @@hello world + +welcome to lyshark blog#最后,生成的lyshark.patch就是補丁文件了,我們可以使用下面的命令對old文件打補丁了.◆patch 文本打入補丁◆
patch命令被用于為開放源代碼軟件安裝補丁程序,讓用戶利用設置修補文件的方式,修改更新原始文件.如果一次僅修改一個文件,可直接在命令列中下達指令依序執行,如果配合修補文件的方式則能一次修補大批文件,這也是Linux系統核心的升級方法之一.
注意:精簡模式下沒有這個命令,需要執行 yum install -y patch 安裝一下
[root@localhost ~]# patch --help Usage: patch [OPTION]... [ORIGFILE [PATCHFILE]]語法格式:[ patch [-pn] 舊文件 < *.patch ]-p:設置要剝離的目錄層數 n:代表補丁文件中記錄的文件old所在目錄層數,用于更新old文件時匹配正確路徑----------------------------------------------------------------- 說明: 給old文件打補丁[root@localhost ~]# ls lyshark.patch new old[root@localhost ~]# patch -p2 old < lyshark.patch patching file old[root@localhost ~]# cat old hello worldwelcome to lyshark blog[root@localhost ~]# cat new hello worldwelcome to lyshark blog總結
以上是生活随笔為你收集整理的Linux正则与文本处理工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 咿呀咿呀哟
- 下一篇: 运行自定义映像。linux,安装和使用v