三劍客
Linux
下常用的增刪改查工具:Grep
、Sed
、Awk
Grep
用於常規的查詢操作雖然方便,但最大的弊端是查出來不能增、刪、改,導致寫腳本會很不方便,這個時候就需要 Sed
和 Awk
這樣的工具來實現
因此 Sed
和 Awk
工具就彌補了 Grep
的短板
三大工具,三劍客
Grep
文本過濾命令
grep root passwd
抓取字符串 root
grep ^root passwd
抓取首字符串 root
grep root$ passwd
抓取尾字符串 root
grep -i root passwd
抓取字符串 root 忽略大小寫
grep -E "root|ROOT" passwd
抓取多項條件
grep -Ei "^root|root$" passwd | gerp -i root
抓取開始root
、結尾root
並且忽略大寫下
grep -Ei "^root|root$" -v passwd | gerp -i root
-v
參數爲反向輸出
抓取中間root
並且忽略大寫下
grep -2 ROOT passwd
抓取中間字符串
grep -n2 ROOT passwd
抓取中間字符串並且排序
Grep
正則表達式
vim test
grep xy test
抓取xy
字符串
grep x test
抓取x
字符
grep y test
抓取y
字符
grep x*y test
抓取 所有
y
字符,並且抓取xy
grep x.y test
grep x..y test
grep x....y test
grep x......y test
抓取以
x
開始、以y
結尾的字符串
.
表示抓取中間字符串的位數
grep x. test
grep x.. test
grep x... test
抓取以
x
開始、以.
結尾的字符串
grep .y test
grep ..y test
grep ...y test
抓取以
y
結尾的,以.
開始的字符串
Grep
中字符的匹配次數
grep -E x?y test
?
表示字符出現 0-1 次
grep -E x+y test
x+y
表示字符出現 1 至任意次
grep -E x{n}y test
字符
x
出現 n 次 、字符y
出現 1次
grep -E xy{n} test
字符
x
出現 1 次 、字符y
出現 n 次
grep -E "\<x{n}y" test
字符
x
出現 n 次 、字符y
出現 1 次 並且從行首抓取
grep -E "x{n}y\>" test
字符
x
出現 n 次 、字符y
出現 1 次 並且從行尾抓取
grep -E "\<x{n}y\>" test
字符
x
出現 n 次 、字符y
出現 1 次 並且從中間抓取
grep -E "x{n,}y" test
字符
x
至少出現 n 次 、字符y
出現 1 次
grep -E "xy{n,}" test
字符
x
至少出現 1 次 、字符y
出現 n 次
grep -E "(xy){n,}" test
字符串
xy
至少出現 n 次
Sed
行編輯器
stream editor
用來操作純 ASCII 碼的文本
處理時,把當前處理的行存儲在臨時緩衝區中,稱爲“模式空間”(pattern space)可以指定僅僅處理哪些行 符合模式條件的處理
不符合條件的不予處理
處理完成之後把緩衝區的內容送往屏幕
接着處理下一行,這樣不斷重複,直到文件末尾
Sed
字符處理
cp /etc/passwd .
cat passwd
cp /etc/fstab .
cat fstab
P
顯示
sed -n '5p' fstab
只顯示第五行內容
sed -n '/#/p' fstab
只顯示以 # 開頭的行
sed -n '/#/!p' fstab
除 # 開頭的行都顯示
sed -n '/UUID/p' fstab
只顯示 UUID 開頭的行
sed -n '2p' fstab
只顯示第二行
sed -n '2p;6p' fstab
只顯示第二行和第六行
sed -n '2p,6p' fstab
只顯示第二行到第六行
sed -n '2p,6!p' fstab
除第二行到第六行,其餘行均顯示
D
刪除
sed '/^UUID/d' fstab
不顯示 uuid 行
sed '1,4d' fstab
不顯示 1–4 行
sed '1d;4d' fstab
不顯示第一行與第四行
sed '/^UUID/!d' fstab
只顯示 UUID 行
反向不顯示 UUID 行
a
添加
sed '/^UUID/a \hello world' fstab
在以UUID開頭行的下一行開始添加內容
sed '/^UUID/a \hello \nworld' fstab
在以UUID開頭行的下一行開始添加內容,因爲有換行符存在,所以自動換行
c
替換
sed '/^UUID/c Hello \nWorld' fstab
替換所有以 UUID 開頭的行爲 Hello World 因爲有換行符存在,所以自動換行
w
寫入
sed '/^UUID/w /test1' fstab
除UUID開頭行以外的其它行內容全部寫入 /test1 裏
sed -n '/^UUID/w /test2' fstab
UUID開頭行的內容全部寫入 /test2 裏
i
插入
sed '/^UUID/i \hello \nworld' fstab
在以UUID開頭行的上一行開始添加內容,因爲有換行符存在,所以自動換行
Sed
其他用法
sed '=' pssswd
每行上一行添加行號
sed '=' passwd | sed 'N;s/\n//g'
每行開頭添加行號
sed '=' passwd | sed 'N;s/\n/ /g'
給每行開頭添加行號並且添加一個空格符
sed '/^#/=' fstab
以 # 開頭內容上一行添加行號
sed '/^UUID/=' fstab
以 UUID 開頭內容上一行添加行號
sed '/^UUID/=' fstab > file1
以 UUID 開頭內容上一行添加行號,並且保存到 file1文件內
sed '/^#/=' fstab -i file1
在#開頭的所有行上面添加行號並且保存到 file1文件內
sed '5r /root/Desktop/test3' fstab
test3 文件內容添加到第五行下面
vim rule
cat rule
sed -f rule fstab
rule文件中每行是一個操作命令
sed '$!G' passwd
除去最後一行,其餘每行下一行添加空白行
sed 'G' passwd
每行下面添加空白行
sed '1,5s/#//g' fstab
第一行至第五行 # 替換成 空格符
sed '1,5s/#/ /g' fstab
第一行至第五行 # 替換成 兩個空格符
sed '5s/#//g' fstab
第五行 # 替換成 空格符
sed 's/\// $ /g' fstab
所有 / 轉換成 $
sed 's/sbin/test/g' passwd
sbin 替換成 test
sed 's/sbin/test/g;s/nologin/hello/g' passwd
sbin 替換成 test 並且 nologin 替換成 hello
sed '/bin/,/lp/s/sbin/test/g' passwd
從 bin 行開始到 lp行結束,所有 sbin 替換成 test
Awk
報告生成器
處理機制
逐行處理文本,支持在處理第一行之前做一些準備工作,以及在處理完最後一行做一些總結性質的工作,在命令格式上分別體現如下:
BEGIN{}
讀取第一行文本之前執行,一般用來初始化操作
{}
逐行處理,逐行讀入文本執行相應的處理,是最常見的編輯指令塊
END{}
處理完最後一行文本之後執行,一般用來輸出處理結果
awk '{print FILENAME}' passwd
輸出文件名稱
文件有多少行內容,輸出多少行文件名
cat -n passwd
awk '{print NR}' passwd
NR
表示行
awk '{print NF}' passwd
NF
表示列
awk -F : '{print NF}' passwd
-F
指定分隔符表示以 : 分隔了多少列
awk '{print NR,ptint NF}' passwd
表示有多少行,多少列
awk '{print NR=1,ptint NF}' passwd
表示第一行有1列
awk -F : '{print NR=5,ptint NF}' passwd
表示第五行以 : 分隔了7列
awk -F : 'BEGIN{print "NAME"}{print NR}' passwd
從 NAME 爲第一行開始依次輸出多少行
awk -F : 'BEGIN{print "NAME"}{print NR}END{print "END"}' passwd
以 : 分隔列從 NAME 爲第一行開始依次輸出多少行 END 爲結束行
awk -F : 'BEGIN{print "NAME"}{print $1}END{print "END"}' passwd
以 : 分隔列從 NAME 爲第一行開始依次輸出每行第一列內容 END 爲結束行
awk -F : 'BEGIN{print "NAME"}{print $1}END{print "END"}' passwd
以 : 分隔列從 NAME 爲第一行開始依次輸出每行第一列和第二列內容(分行顯示) END 爲結束行
awk -F : 'BEGIN{print "NAME"}{print $1,$3}END{print "END"}' passwd
以 : 分隔列從 NAME 爲第一行開始依次輸出每行第一列和第三列內容(一行顯示) END 爲結束行
awk -F : 'BEGIN{print "NAME"}{print $0}END{print "END"}' passwd
以 : 分隔列從 NAME 爲第一行依次輸出全部內容 END 爲結束行
awk -F : 'BEGIN{print "NAME"}{print $1="";print $0}END{print "END"}' passwd
以 : 分隔列第一列爲空從 NAME 爲第一行依次輸出剩餘全部內容 END 爲結束行
awk -F : 'BEGIN{print "NAME"}{print $1="";print $0}END{print "END"}' passwd | sed 's/ /:/g'
以 : 分隔列第一列爲空從 NAME 爲第一行空格符替換成 :依次輸出剩餘全部內容 END 爲結束行
awk '/bash$/{print}' passwd
輸出以 bash 結尾的行
awk '!/bash$/{print}' passwd
輸出除 bash 結尾的其它行
passwd 文件分別添加了test1、test2 兩行內容以供測試使用
awk '!/bash$/&&!/nologin/{print}' passwd
輸出除 bash與nologin 結尾的其它行
awk '/bash$/||/nologin/{print}' passwd
輸出除 bash或nologin 結尾的行
awk -F : '/bash$/{print $1}' /etc/passwd
以 : 分隔列輸出以 bash 結尾的第一列
awk -F : '/bash$/||/sh$/{print $1}' /etc/passwd
以 : 分隔列輸出以 bash 或者 sh 結尾的第一列
awk 'BEGIN{n=0}/bash$/{n++}END{print n}' /etc/passwd
從 n=0 開始,n=n+1 依次遞增輸出 n 的最終循環次數
awk '/^r/{print}' passwd
輸出以 r 字符開頭的行
awk '/^[a-c]/{print}' passwd
輸出以 [a-c] 字符開頭的行
awk -F : '$6~/\<bin/{print}' passwd
以 : 分隔列輸出第六列以 bin 開頭的行
awk -F : '$6!~/\<bin/{print}' passwd
以 : 分隔列輸出除第六列以 bin 開頭的其它行
awk -F : 'BEGIN{n=0}{n++}END{print n}' /etc/passwd
以 : 分隔列從 n=0 開始,n=n+1 依次遞增輸出 n 的最終循環次數
awk -F : 'BEGIN{n=0}/bash$/{n++}END{print n}' /etc/passwd
以 : 分隔列從 n=0 開始,以 bash 結尾 n=n+1 依次遞增輸出 n 的最終循環次數
awk -F : 'BEGIN{n=0}/bash$/&&$6!~/^\/home/{n++}END{print n}' /etc/passwd
以 : 分隔列從 n=0 開始,以 bash 結尾並且第六列不抓取 /home 字符串 n=n+1 依次遞增輸出 n 的最終循環次數
awk -F : 'BEGIN{n=0}/bash$/&&$6!~/^\/home/{print}END{print n}' /etc/passwd
以 : 分隔列從 n=0 開始,以 bash 結尾並且第六列不抓取 /home 字符串 輸出 n 的行及 n 的最終循環次數
awk -F : 'BEGIN{n=0}/bash$/&&$6!~/^\/home/{print}END{print n;n++}'/etc/passwd
以 : 分隔列從 n=0 開始,以 bash 結尾並且第六列不抓取 /home 字符串 輸出 n 的行及 n 的最終循環次數
輸出完成後,再循環,0+1=1
但已經輸出完成,故不統計次數
awk -F : 'BEGIN{n=0}/bash$/&&$6!~/^\/home/{print;n++}END{print n}' /etc/passwd
以 : 分隔列從 n=0 開始,以 bash 結尾並且第六列不抓取 /home 字符串 輸出 n 的行及 n 的最終循環次數
先循環,在輸出,0+1=1
輸出次數已統計,再輸出完成,故統計次數
實驗:
輸出 ens33 網卡的 ip
ifconfig ens33 | awk '/inet\>/{print $2}'
以 inet 末尾開始輸出第二列
統計在系統中可以登錄的用戶
awk -F : /bash$/'{print $1}' /etc/passwd
以 : 分隔列,以 bash 爲結尾,輸出所有第一列內容