Shell—grep、sed、awk
Shell學習
Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 的橋梁。Shell 既是一種命令語言,又是一種程序設計語言。
Shell 是指一種應用程序,這個應用程序提供了一個界面,用戶通過這個界面訪問操作系統內核的服務。
Shell是 Linux系統中自帶的語言
【擴展】:
機器語言
匯編語言
高級語言
- 編譯型 ===> 翻譯 ===> 計算機 (跨平臺性能差,執行速度快)
- 解釋型 ===> 解釋器 ===> 翻譯 ===> 計算機 (跨平臺性能強,執行速度慢)
1. Shell如何執行用戶的指令
Shell有兩種執行指令的方式
- 用戶事先編寫一個sh腳本文件,內含Shell腳本,然后使用Shell程序執行該腳本,這種方式習慣稱為Shell編程
- 用戶直接在Shell界面上執行Shell命令,由于Shell界面的關系,大家習慣一行行的書寫,很少寫成成套的程序來執行,所以也稱命令行
2. Shell的分類
Linux中默認的Shell是 /bin/bash ,流行的Shell有ash、bash、ksh、csh、zsh等,不同的Shell都有自己的特點以及用途
3. grep命令
3.1 grep 命令格式
功能:grep命令是Linux系統中最重要的命令之一,功能是從文本文件或管道數據流中篩選匹配的行和數據,如果再配合正則表達式,功能十分強大,是Linux運維人員必備的命令
grep [選項] pattern filename... 命令 參數 匹配模式 文件數據- 在每個file 或是標準輸入中查找 pattern ,默認pattern是一個基本正則表達式
- 用于查找內容包含指定的范本樣式的文件,如果發現某文件的內容符合所指定的范本樣式,預設grep指令會把含有范本樣式的那一列顯示出來。若不指定任何文件名稱,或是所給予的文件名為“-”,則grep指令會從標準輸入設備讀取數據。
3.2 grep 命令選項
grep常用參數:
grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN]... [-f FILE]... [FILE...]OPTIONS: -a 不要忽略二進制數據。 -A<顯示列數> 除了顯示符合范本樣式的那一行之外,并顯示該行之后的內容。 -b 在顯示符合范本樣式的那一行之外,并顯示該行之前的內容。 -c 計算符合范本樣式的列數。 -C<顯示列數>或-<顯示列數> 除了顯示符合范本樣式的那一列之外,并顯示該列之前后的內容。 -d<進行動作> 當指定要查找的是目錄而非文件時,必須使用這項參數,否則grep命令將回報信息并停止動作。 -e<范本樣式> 指定字符串作為查找文件內容的范本樣式。 -E 將范本樣式為延伸的普通表示法來使用,意味著使用能使用擴展正則表達式。 -f<范本文件> 指定范本文件,其內容有一個或多個范本樣式,讓grep查找符合范本條件的文件內容,格式為每一列的范本樣式。 -F 將范本樣式視為固定字符串的列表。 -G 將范本樣式視為普通的表示法來使用。 -h 在顯示符合范本樣式的那一列之前,不標示該列所屬的文件名稱。 -H 在顯示符合范本樣式的那一列之前,標示該列的文件名稱。 -i 忽略字符大小寫的差別。 -l 列出文件內容符合指定的范本樣式的文件名稱。 -L 列出文件內容不符合指定的范本樣式的文件名稱。 -n 在顯示符合范本樣式的那一列之前,標示出該列的編號。 -q 不顯示任何信息。 -R/-r 此參數的效果和指定“-d recurse”參數相同。 -s 不顯示錯誤信息。 -v 反轉查找。 -w 只顯示全字符合的列。 -x 只顯示全列符合的列。 -y 此參數效果跟“-i”相同。 -o 只輸出文件中匹配到的部分。 --color: 匹配到的內容高亮顯示 --include: 指定匹配的文件類型 --exclude: 過濾不需要匹配的文件類型3.3 grep 實例
查找指定進程
不想顯示grep本身進程,需在grep后加 -v 參數
[root@10-255-1-182 ~]# ps -ef|grep bash root 387 18830 0 Sep15 ? 00:00:00 bash root 2580 18830 0 Sep15 ? 00:00:00 bash root 2707 4872 0 Jul30 ? 00:00:00 bash root 2908 12870 0 Sep04 pts/0 00:00:00 bash root 13493 4872 0 Sep22 ? 00:00:00 bash root 15766 16382 0 12:01 pts/0 00:00:00 grep --color=auto bash # grep本身進程 root 16382 16339 0 10:24 pts/0 00:00:00 -bash root 21380 18830 0 Aug01 ? 00:00:00 bash root 22622 4872 0 Aug18 ? 00:00:00 bash輸出test2.txt中含有從test.txt文件中讀取出的關鍵字的內容行
[root@10-255-1-182 ~]# cat test.txt 周杰倫[root@10-255-1-182 ~]# cat test2.txt 相見恨晚-彭佳慧.mp3 稻香-周杰倫.MP3 等你下課(with楊瑞代)-周杰倫.MP3 簡單愛-周杰倫.MP3 繁華的寂靜-文武貝.mp3 給我一首歌的時間-周杰倫.MP3 芊芊-回音哥.mp3 花沐然-不能說的密碼(抖音版).mp3 蒲公英的約定-周杰倫.MP3[root@10-255-1-182 ~]# cat test2.txt | grep -f test.txt 稻香-周杰倫.MP3 等你下課(with楊瑞代)-周杰倫.MP3 簡單愛-周杰倫.MP3 給我一首歌的時間-周杰倫.MP3 蒲公英的約定-周杰倫.MP3從文件中讀取關鍵詞進行搜索且顯示行號
【注意】:n 必須在 f前面
[root@10-255-1-182 ~]# cat test2.txt | grep -nf test.txt 2:稻香-周杰倫.MP3 3:等你下課(with楊瑞代)-周杰倫.MP3 4:簡單愛-周杰倫.MP3 6:給我一首歌的時間-周杰倫.MP3 9:蒲公英的約定-周杰倫.MP3找出以’稻’開頭的內容
[root@10-255-1-182 ~]# cat test2.txt | grep ^稻 稻香-周杰倫.MP3輸出非’稻’開頭的內容
[root@10-255-1-182 ~]# cat test2.txt | grep ^[^稻] 相見恨晚-彭佳慧.mp3 等你下課(with楊瑞代)-周杰倫.MP3 簡單愛-周杰倫.MP3 繁華的寂靜-文武貝.mp3 給我一首歌的時間-周杰倫.MP3 芊芊-回音哥.mp3 花沐然-不能說的密碼(抖音版).mp3 蒲公英的約定-周杰倫.MP3 過客-阿涵.mp3 過期的愛情-雨宗林.mp3 這片海-顧莉雅.mp3 避雨-任然.mp3 那么驕傲-周玥徐薇.mp3 青山黛瑪-そばにいるね(留在我身邊).mp3 顧莉雅-寂寞花火.mp34. sed命令
4.1 sed 介紹
sed (stream editor ) 流編輯器,常用來進行文本替換工作,與常用的交互式編輯器(vim)不同,sed 編輯器以批處理的方式來編輯文件,這比交互式編輯器快得多,可以快速的完成對數據的編輯修改。
sed是操作、過濾和轉換文本內容的強大工具。常用功能包括對文件實現快速增刪改查,其中查詢的功能中最常用的兩大功能是過濾(過濾指定字符串)、取行(取出指定行)。
sed編輯器會執行以下操作:
- 一次從輸入中讀取一行數據
- 根據所提供的編輯器命令匹配數據
- 按照命令修改流中的數據
- 將新的數據輸出到STDOUT
sed 的工作原理
sed 命令是面向 行 進行處理的,每一次處理一行內容。處理時,sed 會把要處理的行存儲在緩沖區中,接著用 sed 命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。接著處理下一行,這樣不斷重復,直到文件末尾。這個緩沖區被稱為“模式空間”(pattern space)。
在這個處理過程中,sed 命令并不會對文件本身進行任何更改。
例如: 利用sed刪除test.txt中帶b的內容,并沒有改變原文件的內容,刪除只是在模式空間執行的
[root@10-255-1-182 ~]# cat test3.txt zhb zhb htt htt [root@10-255-1-182 ~]# sed '/b/d' test3.txt # d 表示的刪除 htt htt [root@10-255-1-182 ~]# cat test3.txt zhb zhb htt htt4.2 sed 命令格式
sed [options] edit_commands [file]注意:sed 和 grep 不一樣,不管是否找到指定的模式,它的退出狀態都是0,只有當命令存在語法錯誤時,sed的退出狀態才是非0
4.3 sed 支持正則表達式
^ 匹配行開始,如:/^sed/匹配所有以sed開頭的行。 $ 匹配行結束,如:/sed$/匹配所有以sed結尾的行。 . 匹配一個非換行符的任意字符,如:/s.d/匹配s后接一個任意字符,最后是d。 * 匹配0個或多個字符,如:/*sed/匹配所有模板是一個或多個空格后緊跟sed的行。 [] 匹配一個指定范圍內的字符,如/[ss]ed/匹配sed和Sed。 [^] 匹配一個不在指定范圍內的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一個字母開頭,緊跟ed的行。 \(..\) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替換成lovers。 & 保存搜索字符用來替換其他字符,如s/love/**&**/,love這成**love**。 \< 匹配單詞的開始,如:/\<love/匹配包含以love開頭的單詞的行。 \> 匹配單詞的結束,如/love\>/匹配包含以love結尾的單詞的行。 x\{m\} 重復字符x,m次,如:/0\{5\}/匹配包含5個0的行。 x\{m,\} 重復字符x,至少m次,如:/0\{5,\}/匹配至少有5個0的行。 x\{m,n\} 重復字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10個0的行。4.4 sed 常用選項options
-n:不輸出模式空間內容到屏幕,即不自動打印,只打印匹配到的行 -e:多點編輯,對每行處理時,可以有多個Script -f:把Script寫到文件當中,在執行sed時-f 指定文件路徑,如果是多個Script,換行寫 -r:支持擴展的正則表達式 -i:直接將處理的結果寫入文件,即改變原文件 -i.bak:在將處理的結果寫入文件之前備份一份4.5 sed 編輯命令commands
d:刪除模式空間匹配的行,并立即啟用下一輪循環 p:打印當前模式空間內容,追加到默認輸出之后 a:在指定行后面追加文本,支持使用\n實現多行追加 i:在行前面插入文本,支持使用\n實現多行追加 c:替換行為單行或多行文本,支持使用\n實現多行追加 w:保存模式匹配的行至指定文件 r:讀取指定文件的文本至模式空間中匹配到的行后 =:為模式空間中的行打印行號 !:模式空間中匹配行取反處理 s///:查找替換,支持使用其它分隔符,如:s@@@,s###;加g表示行內全局替換;在替換時,可以加一下命令,實現大小寫轉換\l:把下個字符轉換成小寫。\L:把replacement字母轉換成小寫,直到\U或\E出現。\u:把下個字符轉換成大寫。\U:把replacement字母轉換成大寫,直到\L或\E出現。\E:停止以\L或\U開始的大小寫轉換4.6 sed 高級編輯命令
h:把模式空間中的內容覆蓋至保持空間中 H:把模式空間中的內容追加至保持空間中 g:從保持空間取出數據覆蓋至模式空間 G:從保持空間取出內容追加至模式空間 x:把模式空間中的內容與保持空間中的內容進行互換 n:讀取匹配到的行的下一行覆蓋 至模式空間 N:讀取匹配到的行的下一行追加 至模式空間 d:刪除模式空間中的行 D:刪除 當前模式空間開端至\n 的內容(不再傳 至標準輸出),放棄之后的命令,但是對剩余模式空間重新執行sed !: 表示后面的命令對所有沒有被選定的行發生作用
讀取第二行的下一行,然后輸出模式空間的內容,此時模式空間中有兩行
[root@10-255-1-182 ~]# cat test2.txt |sed -n '2{N;p}' 繁華的寂靜-文武貝.mp4 給我一首歌的時間-周杰倫.MP3 芊芊-回音哥.mp44.7 sed 替換標志
g:在行內進行全局替換 w:將行寫入文件 x:交換暫存緩沖區與模式空間的內容 y:將字符裝換為另一字符4.8 實例
sed 用s進行文本替換
[root@10-255-1-182 ~]# cat test2.txt 稻香-周杰倫.MP3 等你下課(with楊瑞代)-周杰倫.MP3 簡單愛-周杰倫.MP3 繁華的寂靜-文武貝.mp3 給我一首歌的時間-周杰倫.MP3 芊芊-回音哥.mp3 花沐然-不能說的密碼(抖音版).mp3 蒲公英的約定-周杰倫.MP3 過客-阿涵.mp3 過期的愛情-雨宗林.mp3 這片海-顧莉雅.mp3 [root@10-255-1-182 ~]# sed 's/3/4/' test2.txt 稻香-周杰倫.MP4 等你下課(with楊瑞代)-周杰倫.MP3 簡單愛-周杰倫.MP3 繁華的寂靜-文武貝.mp4 給我一首歌的時間-周杰倫.MP3 芊芊-回音哥.mp4 花沐然-不能說的密碼(抖音版).mp4 蒲公英的約定-周杰倫.MP4 過客-阿涵.mp3 過期的愛情-雨宗林.mp3 這片海-顧莉雅.mp3默認情況下,替換命令只會替換掉目標文本在每行第一次出現的地方。
sed 's/3/4/g' test2.txt # g 表示替換每行所有匹配到的內容sed 's/3/4/5' test2.txt # 5 表示替換每行第5個匹配到的內容sed 's/3/4/g w test4.txt' test2.txt # 將替換后的文件寫入到test.txt 文件中sed '2,4 s/3/4/g' test2.txt # 替換2到4行,全行替換sed 命令插入和附加文本
sed 編輯器使用i命令來向數據流中插入文本行,使用a命令來向數據流中附加文本行,
- i 是在指定行前增加一個新行,
- a是在指定行后增加一個新行
sed 命令修改行
使用命令c可以將數據流中的整行文本修改為新的行
sed '3 c\告白氣球、告白氣球' test2.txt # 將第3行替換成'告白氣球、告白氣球'5. awk 命令
5.1 awk 介紹
awk不僅是Linux系統一個命令,也是種編程語言,可以處理數據/文件生成Excel。
awk是一個強大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數據分析并生成報告時,顯得尤為強大。
簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。
5.2 awk 語法格式
5.2.1 awk 命令行方式
awk [-F filed-separator] 'commands' input-file(s) awk [選項參數] 'commands' var=value file(s)- commands 是真正的AWK命令;[-F 域分隔符]是可選的;input-file(s)是待處理文件
- awk中,文件的每一行中,由域分隔符分開的每一項稱為一個域。通常在不指定-F 域分隔符的情況下,默認域分隔符是空格
5.2.2 awk 命令插入一個單獨文件調用
awk -f awk-script-file input-file(s) awk [選項參數] -f scriptfile var=value file(s)- -f 選項加載 awk-script-file 中的awk腳本,input-file(s)是待處理的文件
5.2.3 shell腳本方式
- 將所有的awk命令插入一個文件,并使 awk 程序可執行,然后awk命令解釋器作為腳本的首行,一遍通過鍵入腳本名稱來調用,相當于shell腳本首行的:#!/bin/sh 可以換成:#!/bin/awk
5.3 awk工作原理
awk工作流程可分為三個部分:
- 讀輸入文件之前執行的代碼段(由BEGIN關鍵字標識)
- 主循環執行輸入文件代碼段
- 讀輸入文件之后的代碼段(由END關鍵字標識)
5.3.1 awk命令結構
awk 'BEGIN{ commands } parrent{ commands } END{ commands }'開始塊(BEGIN)
BEGIN {awk-commands}-
開始塊就是在程序啟動的時候執行的代碼部分,并且它在整個過程中只執行一次
-
BEGIN是awk的關鍵字,必須大寫
-
開始部分是可選的
主體塊(BODY)
/pattern/{awk-commands}結束塊(END)
END {awk-commands}END也是awk的關鍵字,必須大寫,也是可選的
5.4 awk 選項參數說明
-
-F fs or --field-separator fs
指定輸入文件分隔符,fs是一個字符串或者是一個正則表達式
-
-v var=value or --asign var=value
復制一個用戶定義變量
-
-f scriptfile or --file scriptfile
從腳本文件中讀取awk命令
5.5 awk 基本用法
5.5.1 行匹配語句(默認分隔符)
awk '{[pattern] action}' {filenames} # 行匹配語句 awk '' 只能用單引號例:每行按空格分割,輸出文件中的1、4項
默認情況下,awk 會將如下變量分配給它在文本行中發現的數據字段:
- $0 代表整個文本行;
- $1 代表文本行中的第 1 個數據字段;
- $2 代表文本行中的第 2 個數據字段;
- $n 代表文本行中的第 n 個數據字段。
5.5.2 指定分隔符
awk -F #-F相當于內置變量FS, 指定分割字符例:
# 使用","分割 [root@10-255-1-182 ~]# awk -F, '{print $1,$2}' log.txt this is a test Are you like awk 告白 氣球 周 杰倫 手寫 的從前 周 杰倫 # 或者使用內建變量 [root@10-255-1-182 ~]# awk 'BEGIN{FS=","} {print $1,$2}' log.txt this is a test Are you like awk 告白 氣球 周 杰倫 手寫 的從前 周 杰倫 # 使用多個分隔符.先使用空格分割,然后對分割結果再使用","分割 [root@10-255-1-182 ~]# awk -F '[ ,]' '{print $1,$2,$3}' log.txt this is a Are you like 告白 氣球 手寫 的從前5.5.3 設置變量
awk -v # 設置變量例:
[root@10-255-1-182 ~]# awk -va=1 '{print $1,$1+a}' log.txt this 1 Are 1 告白 1 手寫 1 [root@10-255-1-182 ~]# awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt this 1 thiss Are 1 Ares 告白 1 告白s 手寫 1 手寫s5.5.4 調用腳本
awk -f {awk腳本} {文件名}例:
[root@10-255-1-182 ~]# cat score.txt 張三 1001 80 99 100 李四 1002 92 78 95 王五 1003 78 98 77 狗蛋 1004 98 89 56 [root@10-255-1-182 ~]# cat aaa.awk #!/bin/awk -f # 運行前 BEGIN {math = 0english = 0computer = 0printf "姓名 學號 數學 英語 計算機 總分\n"printf "*******************************\n" }# 運行中 {math+=$3english+=$4computer+=$5printf "%-6s %-4s %-4d %4d %4d %4d\n", $1, $2, $3, $4, $5, $3+$4+$5 }# 運行后 END {printf "*******************************\n"printf "TOTAL:%10d %8d %8d \n", math, english, computerprintf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR } [root@10-255-1-182 ~]# awk -f aaa.awk score.txt 姓名 學號 數學 英語 計算機 總分 ******************************* 張三 1001 80 99 100 279 李四 1002 92 78 95 265 王五 1003 78 98 77 253 狗蛋 1004 98 89 56 243 ******************************* TOTAL: 348 364 328 AVERAGE: 87.00 91.00 82.00運算符
| = += -= *= /= %= ^= **= | 賦值 |
| ?: | C條件表達式 |
| || | 邏輯或 |
| && | 邏輯與 |
| ~ 和 !~ | 匹配正則表達式和不匹配正則表達式 |
| < <= > >= != == | 關系運算符 |
| 空格 | 連接 |
| + - | 加,減 |
| * / % | 乘,除與求余 |
| + - ! | 一元加,減和邏輯非 |
| ^ *** | 求冪 |
| ++ – | 增加或減少,作為前綴或后綴 |
| $ | 字段引用 |
| in | 數組成員 |
5.5.5 忽略大小寫
[root@10-255-1-182 ~]# cat log.txt this is a test Are you like awk This is a test 告白 氣球 周 杰倫 手寫 的從前 周 杰倫 [root@10-255-1-182 ~]# awk 'BEGIN{IGNORECASE=1} /this/' log.txt this is a test This is a test [root@10-255-1-182 ~]#5.6 awk內置變量
| $n | 當前記錄的第n個字段,字段間由FS分隔 |
| $0 | 完整的輸入記錄 |
| ARGC | 命令行參數的數目 |
| ARGIND | 命令行中當前文件的位置(從0開始算) |
| ARGV | 包含命令行參數的數組 |
| CONVFMT | 數字轉換格式(默認值為%.6g)ENVIRON環境變量關聯數組 |
| ERRNO | 最后一個系統錯誤的描述 |
| FIELDWIDTHS | 字段寬度列表(用空格鍵分隔) |
| FILENAME | 當前文件名 |
| FNR | 各文件分別計數的行號 |
| FS | 字段分隔符(默認是任何空格) |
| IGNORECASE | 如果為真,則進行忽略大小寫的匹配 |
| NF | 一條記錄的字段的數目 |
| NR | 已經讀出的記錄數,就是行號,從1開始 |
| OFMT | 數字的輸出格式(默認值是%.6g) |
| OFS | 輸出記錄分隔符(輸出換行符),輸出時用指定的符號代替換行符 |
| ORS | 輸出記錄分隔符(默認值是一個換行符) |
| RLENGTH | 由match函數所匹配的字符串的長度 |
| RS | 記錄分隔符(默認是一個換行符) |
| RSTART | 由match函數所匹配的字符串的第一個位置 |
| SUBSEP | 數組下標分隔符(默認值是/034) |
例:
# 輸出順序號 NR, 匹配文本行號. [root@10-255-1-182 ~]# awk '{print NR,FNR,$1,$2,$3}' log.txt 1 1 this is a 2 2 Are you like 3 3 This is a 4 4 告白 氣球 周 5 5 手寫 的從前 周 # 指定輸出分隔符 [root@10-255-1-182 ~]# awk '{print $1,$2,$5}' OFS=" $ " log.txt this $ is $ Are $ you $ This $ is $ 告白 $ 氣球 $ 手寫 $ 的從前 $總結
以上是生活随笔為你收集整理的Shell—grep、sed、awk的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python爬取网页
- 下一篇: 0pencv——图像腐蚀