1. 程式人生 > 其它 >Shell之三劍客命令(grep sed awk)

Shell之三劍客命令(grep sed awk)

技術標籤:Shell入門到入墳shell正則表示式linux

文章目錄

1. grep

1. grep介紹

主要用於過濾文字,還支援 管道符(|)

注:不是所有命令都支援放倒管道符後面的。用xargs讓不支援的也也支援管道 例:find … | xargs -I {} -rm -rf {}

2. 基本用法

1. grep使用

grep 選項 ‘命令’ 檔案路徑

注:“命令” 跟 ‘命令’ 一樣

2. grep選項

# -n 顯示行號
grep -n 'root' /etc/passwd
# -o 只顯示過濾成功的內容
grep -n 'root' /etc/passwd  # 只輸出一堆 root
# -i 忽略大小寫 
# -A n  匹配成功的當前行 及其後n行  
# -B n 為前兩行   
# -C n 前後兩行
grep -A 2 'root'
/etc/passwd # -c 顯示出有幾行匹配成功 # -v 取反 ps aux | grep ssh |grep -v grep # -w 只過濾單詞 (連續的字母數字下劃線組成的) grep -w "xiao" a.txt # -r 遞迴的過濾 # -l 顯示匹配成功的檔案 grep -rl "root" /etc/ # 將etc檔案下的全部子檔案子子檔案有root過濾出來 # grep -E 等同於 egrep 擴充套件正則表示式 # --color=auto 顏色 預設就有 # 可以輸入 alias grep 檢視

3. 普通的正則表示式

# ^ 以root開頭 
grep "^root" /etc/passwd
# $ 以root結尾
grep "root$" /etc/passwd
# . 任意一個字元
grep "roo." /etc/passwd
# * 左邊的字元出現0 次 或者無窮次  預設貪婪 a.*b  吃到遠的b 
# 如果想非貪婪 需要 grep -P '.*?'   -P表示支援perl的正則	
grep "ab*" a.txt  # 必須有a  b沒有也行 無數個也行
# [ ] 匹配單個字元   [0-9a-z] 範圍   想匹配 - 則需要放到最左或最右    
# [^0-9 ] 取反    
grep 'a[1x]b' a.txt  # 只對應出  a1b 跟axb  
# 用 < > 或 -w 界定單詞邊界
grep \<22\>  grep -w "22"
# -Pz   P表示啟用perl正則表示式  z表示多行處理 
 使 \n \t 等有效

4. 擴充套件正則表示式 (egerp)

# *  可以沒有也可以多個
# +  1次或者無窮次
# ?  0次或者1次
# {}自己規定次數
ab{0,} 等同於 ab*
ab{1,} 等同於 ab+
ab{0,1} 等同於 ab?
# ( ) 一個括號一個分組   ()()  \1 \2  
egrep "(xiao)12\1"  # 等同於 "xiao12xiao"

# |   左右兩個正則表示式 表示或者關係 
“root|haha”


2. sed

1. sed介紹

sed全稱(stream editor)流式編輯器,sed主要用來自動編輯一個或多個檔案,簡化對檔案的反覆操作,編寫裝換程式等

原理: sed程序會申請一段記憶體,將其劃分為兩部分模式空間保持空間,操作檔案時 一行行讀入模式空間,一行行操作後,預設一行行流出到螢幕上。

:sed不能用$?判斷成功與否,因為退出狀態一直為0 ,只有存在語法錯誤時,sed的退出狀態才不是0

2. 基本用法

1. sed的使用

sed 選項 ‘定位+命令’ 檔案路徑

2. sed的選項

選項功能
-r支援正則表示式(一般都寫)
-i輸出到螢幕的內容輸入到檔案內(預設輸出到螢幕)
-n取消預設輸出
-e(‘3d;3p’)多段規則(sed -e ‘3d’ -e ‘3d’)
-f從檔案讀取規則(sed -f -a.sed a.txt)

3. sed定位

1.行號定位

# 第一行刪除 
sed -r '1d' a.txt
# 1-5行刪除  範圍定位 
sed -r '1,5d' a.txt
# 1 3 6 行刪除  
sed -r '1d;3d;6d' a.txt
# 第一行到最後一行刪除  
sed -r '1,$d' a.txt  

2.正則定位

# 刪除 包含xiao
sed -r '/xiao/d' a.txt  
# 刪除 以xiao結尾
sed -r '/xiao$/d' a.txt  
# 刪除 以xiao開頭
sed -r '/^xiao/d' a.txt  
# 刪除xiao開頭 xiao結尾 中間任意
sed -r '/^xiao.*xiao$/d' a.txt  

: 正則表示式 包含在 \c 正則 c ,c可以是任何字元 用 // 時 前面不需要帶反斜槓(\),當正則包含 路徑時, 可以用 @ (#)包含

3.範圍定位

# 1-5行刪除  範圍定位 
sed -r '1,5d' a.txt

# 從第3行開始 到最近匹配成功的 (n結尾)的正則為止  (非貪婪)
sed -r '3,/n$/d' a.txt

4. 命令

命令功能
a(i)追加到下一行(插入到上一行)
c修改 例: sed -r '3c xxxxxx ’ a.txt
d刪除
s/xxx/yyy/g將xxx換為yyy(xxx與yyy可以正則操作)
&取正則匹配的原內容 ( s/[0-9]$/&xiao/g)效果為最後一個位數字的行 新增上xiao
e多重編輯
i忽略大小寫
取反 例: ‘1,8!d’ 即1-8行以外的刪除
r讀取檔案到目標行 例: sed -r ‘4r 1.conf’ a.txt
w寫入其他檔案
y對應替換 例: ‘y/ab/XY/’ 所有a->X b->Y
q退出 3q 第三行退出,後續不輸出

5. 模式空間 與 保持空間

命令功能
x交換模式空間與保持空間
h模式空間複製/覆蓋 保持空間
H模式空間追加到保持空間
g保持空間複製/覆蓋到模式空間
G保持空間追加到模式空間
n讀取下一行到 /覆蓋 到模式空間
N將下一行新增到模式空間
d刪除預設輸出

瞭解即可:

例子

檔案a.txt內容為

111

222

333

修改為

333

222

111

方式一:

sed -r '1h;1d;2G;2h;2d;3G' a.txt

方式二:

tac a.txt

3. awk

1. awk介紹

awk本身就是一門程式語言,awk命名由來為他的三個作者的首字母

2. 基本用法

1. awk的使用

awk 選項 ‘BEGIN{}模式匹配{}END{}’ 檔案路徑 (也支援放到管道後方)

head -10 /etc/passwd  | awk -F: 'BEGIN{count=0}{print $0;count++}END{print count}'


1. 最先執行:行前處理程式碼 BEGIN{count=0} 
	FS 指定輸入分割符  'BEGIN{count=0;FS=":"}'  效果等同 -F: 
	OFS 指定輸出分隔符 'BEGIN{count=0;FS=":";OFS="-"}' 原來逗號(,)效果為空格 現在改為 - 號
	
2. 再執行:行處理
(1)	
	-F: 效果 以:為界切分成n段 為$1-$n 
	$0 為整行
	NR 行號
	NF 段數
	
(2)
	執行行處理程式碼:{print $0;count++}
(3)
	迴圈,直到所有行處理完畢

3. 最後執行: 行後處理
     END{print count}
     
從檔案中讀取規則則 :awk -F: -f 1.awk /etc/passwd

2. 模式匹配

行定位 
# awk -F: 'NR == 3{print NR,$1}' /etc/passwd
NR == 3 第三行
NR >=1 && NR<=3
NR == 1 ||NR == 2

正則定位
# awk -F: '/^root/{print NR,$1}' /etc/passwd
^root   root開頭 

部段正則匹配
# awk -F: '$1 ~ /root/{print NR,$1}' /etc/passwd
輸出 第一段中 包含root的行

範圍匹配  大於等於3 小於等於7 且包含root的行
awk 'NR >= 3 && NR <=7 && /root/{print NR,$0}' /etc/passwd

# !()的使用 取反
awk -F: '!($1 ~ /root/){print NR,$1}' /etc/passwd
awk -F: '$1 !~ /root/{print NR,$1}' /etc/passwd

3. 格式化輸出(print -> printf)

awk -F: '{printf "行號:%s---使用者名稱:%s\n",NR,$1}' /etc/passwd 

4. 流程控制

awk -F: 'BEGIN{X=0;y=0;z=0}{if ($3 == 0 ){x++} else if ( $3>1 && $3<=999){y++} else {z++}}END{printf "管理員:%s\n系統使用者:%s\n 普通使用者數:%s\n",x,y,z}' /etc/passwd

shell寫法改寫

#!/bin/bahs

x=0
y=0
z=0
for uid in $(awk -F: '{print $3}' /etc/passwd)
do
	if [ $uid -eq 0 ];then
		let x++
	elif [ $uid -ge 1 -a $uid -le 999 ];then
		let y++
	else 
		let z++
	fi
done
printf "管理員:%s\n系統使用者:%s\n 普通使用者數:%s\n" $x $y $z

5. 流程控制

awk '{n=0;while (n<3){print $0,n++}}' a.txt
awk '{for (n=0;n<3;n++){print $0}}' a.txt

6. 陣列

emmmm 累了 用到在學把
在這裡插入圖片描述