Linux命令三剑客:grep、sed、awk总结
文章目錄
- 前言
- 一、grep
- 命令語法
- 實(shí)例
- grep結(jié)合pattern正則
- 二、sed
- 命令語法
- 案例
- 三、awk
- 命令語法
- 實(shí)例
前言
最近看到了幾篇關(guān)于linux命令grep、sed、awk的文章,這里總結(jié)下,方便后面使用。
一、grep
grep命令(grep的全稱:Global search Regular Expression and Print out the line)主要用于文本內(nèi)容的查找。它支持正則表達(dá)式查找。
命令語法
grep提供兩種方式:
◆ grep [option] [pattern] testfile #第一種是從文本中直接使用pattern匹配搜索 ◆ stdout | grep [option] [pattern] #第二種是從標(biāo)準(zhǔn)輸出中處理 grep所提供的option(參數(shù)選項(xiàng))參數(shù)解釋:
實(shí)例
做一個(gè)最簡(jiǎn)單的示例,如下先準(zhǔn)備一個(gè)測(cè)試文件,內(nèi)容如下:
從文本文件中搜索test字符串
可以看到包含有"test"的行被打印出來,默認(rèn)grep是區(qū)分大小寫的。所以"Test","TEST"沒有被匹配出來。
如果想要不區(qū)分大小寫,我們可以加"-i"的參數(shù)。如下:
當(dāng)前我們的測(cè)試文本內(nèi)容比較少,我們?nèi)庋劭梢砸姷绞窃诘趲仔小H绻谋拘袛?shù)較多的情況下那就不太方便了,這里就可以用到"-n"的參數(shù)
包含有"test"的并且不區(qū)分大小寫的行在開頭會(huì)顯示行號(hào),現(xiàn)在的結(jié)果中匹配的關(guān)鍵字所在行全部?jī)?nèi)容都會(huì)輸出。
如果只想要看到匹配的關(guān)鍵字,怎么辦?使用"-o"參數(shù)即可
有時(shí)候我們需要對(duì)整個(gè)目錄去搜索關(guān)鍵字,如果直接使用grep “test” 目錄名,會(huì)報(bào)錯(cuò)。加參數(shù)’-r’就可以避免這個(gè)問題
可以看到shellTest目錄下的兩支文件test1.txt以及testfile都包含test被打印出來了
“-q”選項(xiàng)表示使用靜默模式,在此模式下grep命令不會(huì)有任何的打印結(jié)果,無論是否有匹配到。一般來說我們可以根據(jù)echo $?來查看上一條指令(grep)的執(zhí)行結(jié)果,如果返回結(jié)果為0,表示grep有匹配到了,如果返回結(jié)果為1,表示grep沒有匹配到。
一般我們可以shell腳本中去用if條件分支進(jìn)行判斷,如果echo $?結(jié)果為0,就去執(zhí)行相應(yīng)的操作。
grep結(jié)合pattern正則
前面我們介紹了參數(shù)的基本用法,grep的強(qiáng)大之處其實(shí)是和正則表達(dá)式一起才有作用。
注:本篇文章不會(huì)具體介紹正則表達(dá)式的使用,如果不了解正則表達(dá)式的同學(xué)推薦去看下之前相關(guān)的文章
我們知道在正則表達(dá)式中分為了兩類:
01 基本正則表達(dá)式
◆ . 單個(gè)字符 ◆ * 表示前面的字符連續(xù)出現(xiàn)任意次,包括0次 ◆ ^ 表示錨定行首 ◆ $ 表示錨定行尾 ◆ [a-z] [0-9] 區(qū)間范圍 ......02 擴(kuò)展正則表達(dá)式
◆ ?表示匹配其前面的字符0或1次 ◆ + 表示匹配其前面的字符至少1次,或者連續(xù)多次,連續(xù)次數(shù)上不封頂。 ◆ () 分組 ◆ {} 連續(xù)匹配 ◆ | 匹配多個(gè)表達(dá)式的任何一個(gè) ......如查詢以"lemon"單詞開頭
查找文件中空白行的數(shù)量
連續(xù)字?jǐn)?shù)的正則匹配,如:查找“appium”,p是連續(xù)的
“{2}”表示p連續(xù)出現(xiàn)了兩次,可以發(fā)現(xiàn)結(jié)果是匹配不到的。因?yàn)閧}是擴(kuò)展正則表達(dá)式,grep默認(rèn)是基本正則表達(dá)式,如果需要支持?jǐn)U展正則表達(dá)式,我們需要加"-E"選項(xiàng):
二、sed
sed命令主要用于文本內(nèi)容的編輯。默認(rèn)只處理模式空間,不處理原數(shù)據(jù),而且sed是針對(duì)一行行數(shù)據(jù)來進(jìn)行處理的。Stream Editor文本流編輯,是一個(gè)"非交互式的"面向字符流的編輯器。
常用功能
(1) 、打印功能
能同時(shí)處理多個(gè)文件多行內(nèi)容,可以不對(duì)原文件改動(dòng)把整個(gè)文件輸入到屏幕。
(2)、文本替換
把匹配到模式的內(nèi)容輸入到屏幕上。
(3)、修改文本
可以對(duì)原文件改動(dòng),但是不會(huì)在屏幕上返回結(jié)果。(謹(jǐn)慎使用!!!)
總結(jié):
Sed就是修改文本、替換文本、打印文本的一個(gè)工具。
執(zhí)行流程:
Sed是從文件或管道中讀取一行,處理一行,輸出一行;再讀取一行,再處理一行,再輸出一行…當(dāng)處理一行時(shí),把當(dāng)前處理的行存儲(chǔ)在臨時(shí)緩沖區(qū)中,稱為模式空間(pattern space),接著用sed命令處理緩沖區(qū)中的內(nèi)容,處理完成后,把緩沖區(qū)的內(nèi)容送往屏幕。接著處理下一行,這樣不斷重復(fù),直到文件末尾。如下,簡(jiǎn)單流程圖。
補(bǔ)充:
一次處理一行的設(shè)計(jì)模式使得sed性能很高,sed在讀取大文件時(shí)不會(huì)出現(xiàn)卡頓的現(xiàn)象。
例如:使用vi命令打開幾十M上百M(fèi)的文件,明顯會(huì)出現(xiàn)有卡頓的現(xiàn)象,這是因?yàn)関i命令打開文件是一次性將文件加載到內(nèi)存,然后再打開。Sed就避免了這種情況,一行一行的處理,打開速度非常快,執(zhí)行速度也很快。
命令語法
Sed [選項(xiàng)] 編輯命令 文件 Shell 命令 | sed [選項(xiàng)] 編輯命令常用選項(xiàng)
-n:只顯示匹配處理的行 -e:執(zhí)行多個(gè)編輯命令(一般使用;代替) -i:直接在文件中進(jìn)行修改,不輸出到屏幕 -r:支持?jǐn)U展正則表達(dá)式 -f:從腳本文件中讀取內(nèi)容并執(zhí)行文件中的編輯命令。 補(bǔ)充:這里比較常用的-n -r -e(用;代替)常用編輯命令:
p:打印匹配行 d:刪除匹配行 a:在定位行號(hào)后附加新文本信息 i:在定位行號(hào)后插入新文本信息 c:用新文本替換定位文本 r:從另一個(gè)文件中讀文本,類似輸入重定向(<) w:寫文本到一個(gè)文件,類似輸出重定向(>) s:使用替換模式替換相應(yīng)模式 補(bǔ)充:這里比較常用的p d s案例
案例1:
n 一般和 p連用
//打印文件的3-6行,使用行號(hào)
//打印(^odysee)以odysee開頭的行,使用正則
案例2:
參數(shù)d(刪除匹配行),不會(huì)改變?cè)募?nèi)容
//$表示最后一行,!表示取反,d刪除匹配行,p打印,;多個(gè)命令分割符
//連起來就是只打印文件最后一行
查看原文件,并沒有改變
案例3:
參數(shù)a(在定位行號(hào)后附加新文本信息)
//1a表示在第一行后面追加,也可使用正則
案例4:
參數(shù)i(在定位行號(hào)后插入新文本信息)
//1i:在第一行前插入,可以使用正則
三、awk
awk同sed命令類似,只不過sed擅長(zhǎng)取行,awk命令擅長(zhǎng)取列。(根據(jù)了解awk是一種語言,不過我們只關(guān)注他處理文本的功能,用的好的話幾乎可以取代excel)
原理:一般是遍歷一個(gè)文件中的每一行,然后分別對(duì)文件的每一行進(jìn)行處理。
awk命令主要用于文本內(nèi)容的分析處理。
如果對(duì)處理的數(shù)據(jù)需要生成報(bào)告之類的信息,或者處理的數(shù)據(jù)是按列進(jìn)行處理的,最好使用awk。
命令語法
awk [可選的命令行選項(xiàng)] 'BEGIN{命令 } pattern{ 命令 } END{ 命令 }' 文件名實(shí)例
打印某幾列
$ echo 'I love you' | awk '{print $3 $2 $1}' youloveI我們將字符串 I love you 通過管道傳遞給awk命令,相當(dāng)于awk處理一個(gè)文件,該文件的內(nèi)容就是I love you,默認(rèn)通過空格作為分隔符(不管列之間有多少個(gè)空格都將當(dāng)作一個(gè)空格處理)I love you就分割成三列了。
假如分割符號(hào)為.,可以這樣用
$ echo '192.168.1.1' | awk -F "." '{print $2}' 168條件過濾
我們知道awk的用法是這樣的,那么pattern部分怎么用呢?
awk [可選的命令行選項(xiàng)] 'BEGIN{命令 } pattern{ 命令 } END{ 命令 }' 文件名 $ cat score.txt tom 60 60 60 kitty 90 95 87 jack 72 84 99 $ awk '$2>=90{print $0}' score.txt kitty 90 95 87$2>=90 表示如果當(dāng)前行的第2列的值大于90則處理當(dāng)前行,否則不處理。說白了pattern部分是用來從文件中篩選出需要處理的行進(jìn)行處理的,這部分是空的代表全部處理。pattern部分可以是任何條件表達(dá)式的判斷結(jié)果,例如>,<,==,>=,<=,!=同時(shí)還可以使用+,-,*,/運(yùn)算與條件表達(dá)式相結(jié)合的復(fù)合表達(dá)式,邏輯 &&,||,!同樣也可以使用進(jìn)來。另外pattern部分還可以使用 /正則/ 選擇需要處理的行。
判斷語句
判斷語句是寫在pattern{ 命令 }命令中的,他具備條件過濾一樣的作用,同時(shí)他也可以讓輸出更豐富
$ awk '{if($2>=90 )print $0}' score.txt kitty 90 95 87 $ awk '{if($2>=90 )print $1,"優(yōu)秀"; else print $1,"良好"}' score.txt tom 良好 kitty 優(yōu)秀 jack 良好BEGIN 定義表頭
awk [可選的命令行選項(xiàng)] 'BEGIN{命令 } pattern{ 命令 } END{ 命令 }' 文件名使用方法如下:
$ awk 'BEGIN{print "姓名 語文 數(shù)學(xué) 英語"}{printf "%-8s%-5d%-5d%-5d\n",$1,$2,$3,$4}' score.txt 姓名 語文數(shù)學(xué)英語 tom 60 60 60 kitty 90 95 87 jack 72 84 99這里要注意,我為了輸出格式好看,做了左對(duì)齊的操作(%-8s左對(duì)齊,寬8位),printf用法和c++類似。
不僅可以用來定義表頭,還可以做一些變量初始化的工作,例如
$ awk 'BEGIN{OFMT="%.2f";print 1.2567,12E-2}' 1.26 0.12這里OFMT是個(gè)內(nèi)置變量,初始化數(shù)字輸出格式,保留小數(shù)點(diǎn)后兩位。
END 添加結(jié)尾符
和BEGIN用法類似
$ echo ok | awk '{print $1}END{print "end"}' ok end數(shù)據(jù)計(jì)算
這個(gè)地方我要放大招了!上面的知識(shí)點(diǎn)你都記住了嗎?
$ awk 'BEGIN{print "姓名 語文 數(shù)學(xué) 英語 總成績(jī)"; \ sum1=0;sum2=0;sum3=0;sumall=0} \ {printf "%5s%5d%5d%5d%5d\n",$1,$2,$3,$4,$2+$3+$4;\ sum1+=$2;sum2+=$3;sum3+=$4;sumall+=$2+$3+$4}\ END{printf "%5s%5d%5d%5d%5d\n","總成績(jī)",sum1,sum2,sum3,sumall}'\score.txt 姓名 語文 數(shù)學(xué) 英語 總成績(jī)tom 60 60 60 180 kitty 90 95 87 272jack 72 84 99 255 總成績(jī) 222 239 246 707因?yàn)槊钐L(zhǎng),末尾我用\符號(hào)換行了。。
- BEGIN體里我輸出了表頭,并給四個(gè)變量初始化0
- pattern體里我輸出了每一行,并累加運(yùn)算
- END體里我輸出了總統(tǒng)計(jì)結(jié)果
- 當(dāng)然了,一個(gè)正常人在用linux命令的時(shí)候是不會(huì)輸入那么多格式化符號(hào)來對(duì)齊的,所以新命令又來了
- column -t(鬼知道我為什么會(huì)記得這么多亂七八糟的命令。)
有用的內(nèi)置變量
NF:表示當(dāng)前行有多少個(gè)字段,因此$NF就代表最后一個(gè)字段
NR:表示當(dāng)前處理的是第幾行
FILENAME:當(dāng)前文件名
OFMT:數(shù)字輸出的格式,默認(rèn)為%.6g。表示只打印小數(shù)點(diǎn)后6 位
內(nèi)置函數(shù)
awk定義了很多內(nèi)置函數(shù),用awk來寫shell腳本倒是一個(gè)不錯(cuò)的選擇,但是大多數(shù)我們是用不上的,以下是常用函數(shù)
$ echo 1 2 | awk '{print $1+sqrt($2)}' 2.41421隨機(jī)數(shù),先設(shè)置種子再隨機(jī)
rand() 0 <= n < 1,srand([expr]) |將 rand 函數(shù)的種子值設(shè)置為 Expr 參數(shù)的值,或如果省略 Expr 參數(shù)則使用某天的時(shí)間。
$ echo 1 | awk 'BEGIN{srand()}{print rand()}' 0.929885字符串
系統(tǒng)常用
不常用算數(shù):
參考:
https://www.toutiao.com/i6741262116495294987/
https://www.toutiao.com/a6726544069754880523/
https://www.toutiao.com/a6675158518468706829/
https://www.toutiao.com/a6705966822589465100/
總結(jié)
以上是生活随笔為你收集整理的Linux命令三剑客:grep、sed、awk总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 01Pandas_数据结构
- 下一篇: 【解决】jupyter在deepin安装