Linux三劍客是指的grep、sed、awk三個(gè)命令,grep主打查找功能,sed主要是編輯,awk主要是分割處理。
grep
grep是global regular expressions print的縮寫。grep命令能夠在一個(gè)或者多個(gè)文件中搜索某一特定的字符模式,此模式可以是單一的字符、字符串、單詞或句子。grep可以在文本中查找指定的字符串,是linux中最常用的文本處理工具之一。正則表達(dá)式的通配符如下:
* : 將匹配0個(gè)或者多個(gè)字符。. :將匹配任何一個(gè)字符,且只能是一個(gè)字符。[xyz] :匹配方括號(hào)中的任意一個(gè)字符。[^xyz] :匹配方括號(hào)中的任意一個(gè)字符。^ : 鎖定行的開頭。$ :鎖定行的結(jié)尾。? :匹配前面的子表達(dá)式0次或者1次。+ :匹配前面的子表達(dá)式1次或者多次。| : 匹配于| 符號(hào)前或后的正則表達(dá)式。{n,m} :最少匹配n次,最多匹配m次和BRE的區(qū)別是不需要加\。
在基本的正則表達(dá)式中,使用通配符原本的意思,需要添加\ 作為轉(zhuǎn)義字符。
grep命令用來(lái)在每一個(gè)文件搜索特定的模式,當(dāng)使用grep時(shí),包含指定字符模式的每一行內(nèi)容,都會(huì)被打印到屏幕上,但是使用grep命令并不改變文件中的內(nèi)容。
grep命令格式:grep [選項(xiàng)] 模式 文件名
這里的模式,要么是字符串,要么是正則表達(dá)式。常用的選項(xiàng)如下表。
-
-c :僅列出文件中包含模式的行數(shù),即匹配到的總行數(shù)。 -
-i :忽略模式中的字母大小寫。 -
-l :列出帶有匹配行的文件名。 -
-n :在每一行的最前面列出行號(hào)。 -
-v :列出沒(méi)有匹配模式的行。 -
-w :把代表式當(dāng)做一個(gè)完整的單字符來(lái)搜尋,忽略哪些部分匹配的行。 -
-color=auto 或者-color :表示對(duì)匹配到的文本著色顯示。 -
-o:只顯示符號(hào)條件的字符串,但是不整行顯示,每個(gè)符號(hào)條件的字符串單獨(dú)顯示一行。 -
-w:匹配整個(gè)單詞,如果是字符串中包含這個(gè)單詞,則不做匹配。
如果是搜索多個(gè)文件,grep命令的搜索結(jié)果只顯示文件中發(fā)現(xiàn)匹配模式的文件名,如果搜索單個(gè)文件,grep命令的結(jié)果將顯示每一個(gè)包含匹配模式的行。
sed原理
sed是一種流編輯器,流編輯器會(huì)在編輯器處理數(shù)據(jù)之前基于預(yù)先提供一組規(guī)則來(lái)編輯數(shù)據(jù)流。sed編輯器可以根據(jù)命令來(lái)處理數(shù)據(jù)流中的數(shù)據(jù),這些命令要么從命令行中輸入,要么存儲(chǔ)在一個(gè)命令文本中。
sed是操作、過(guò)濾和轉(zhuǎn)換文本內(nèi)容的強(qiáng)大工具,常用功能增刪改查,過(guò)濾,取行。
sed命令的格式如下:sed [options] [sed-commands] [input-file]
- options常用的有:
-n ---- 抑制默認(rèn)輸出,-e ---- 執(zhí)行多條編輯命令, -i ---- 直接在源文件中修改。 - sed-commands:既可以是單個(gè)sed命令,也可以是多個(gè)sed命令組合。
- input-file:可選項(xiàng),sed還可以從標(biāo)準(zhǔn)輸出如管道獲取輸入。
sed是從文件或者管道中讀取一行,放在模式空間中,進(jìn)行處理,處理完輸出一行,在讀取一行,再處理一行。模式空間是sed內(nèi)部的臨時(shí)緩存,用于存放讀取到的內(nèi)容。
sed可以對(duì)單行或多行進(jìn)行處理,如果在sed命令前面不指定地址范圍,那么默認(rèn)會(huì)匹配所有行。
sed流程
sed的工作流程主要包括讀取、執(zhí)行和顯示三個(gè)過(guò)程。
讀取流程:sed從輸入流(文件、管道、標(biāo)準(zhǔn)輸入)中讀取一行內(nèi)容并存在到臨時(shí)的緩沖區(qū)中(又稱為模式空間)。
執(zhí)行流程:默認(rèn)情況下,所有的sed命令都在模式空間中順利地執(zhí)行,除非指定了行的地址,否則sed命令,將會(huì)在所有的行上依次執(zhí)行。
顯示流程:發(fā)送修改后的內(nèi)容到輸出流。在發(fā)送數(shù)據(jù)后,模式空間將會(huì)被清空,在所有的文件內(nèi)容都被完成處理之前,上述過(guò)程被反復(fù)執(zhí)行,直至內(nèi)容被處理完。
sed選項(xiàng)
sed命令格式:
sed -e '操作' 文件1 文件2 sed -n -e '操作' 文件1 文件2 sed -f 腳本文件 文件1 文件2 sed -e -i '操作' 文件1 文件2
常用選項(xiàng):
-e 或--expression :表示用指定命令來(lái)處理輸入的文本文件,只有一個(gè)操作命令時(shí)可以省略,一般在執(zhí)行多個(gè)操作命令使用。-f 或--file :表示用指定腳本文件來(lái)處理輸入的文本文件。-h 或--help :顯示幫助。-n 或s --quiet:禁止sed編輯器輸出,但可以與p命令一起使用完成輸出。-i :直接修改文本文件。-r ,-E :使用擴(kuò)展正則表達(dá)式-s :將多個(gè)文件視為獨(dú)立文件,而不是單個(gè)連續(xù)的長(zhǎng)文件流。
常用操作:
s :替換指定字符(替換)。d :刪除指定的行(刪除)。a :在指定的行上一行增加一行指定內(nèi)容(增加)。i :在指定的上一行插入一行指定內(nèi)容(插入)。c :將選定行內(nèi)容替換為指定內(nèi)容(替換)。y :字符轉(zhuǎn)換,轉(zhuǎn)換之后的字符長(zhǎng)度必須相同。p :打印,如果同時(shí)指定行,表示打印指定行,如果不指定行,則表示打印所有內(nèi)容;如果有非打印字符,則以Ascii碼輸出。通常與_n選項(xiàng)一起使用。= :打印行號(hào)。l :答應(yīng)數(shù)據(jù)流中的文本和不可打印的ASCII字符。
sed的查找
使用sed命令查看:
方法一:sed ' ' /etc/shadow
root@chengyan-virtual-machine:~# sed ' ' /etc/shadow
root:$6$lvkzBBp4$EL4M3jGWlhVG73hngVOXVO1o3vtTaLIt7uNrlkC1:19201:0:99999:7:::
daemon:*:17379:0:99999:7:::
bin:*:17379:0:99999:7:::
sys:*:17379:0:99999:7:::
sync:*:17379:0:99999:7:::
games:*:17379:0:99999:7:::
man:*:17379:0:99999:7:::
lp:*:17379:0:99999:7:::
mail:*:17379:0:99999:7:::
方法二:sed -n 'p ' /etc/shadow
root@chengyan-virtual-machine:~# sed -n 'p ' /etc/shadow
root:$6$lvkzBBp4$EL4M3jGWlhVG73hngVOXVO1o3vtTaLIt7uNrlkC1:19201:0:99999:7:::
daemon:*:17379:0:99999:7:::
bin:*:17379:0:99999:7:::
sys:*:17379:0:99999:7:::
sync:*:17379:0:99999:7:::
games:*:17379:0:99999:7:::
man:*:17379:0:99999:7:::
lp:*:17379:0:99999:7:::
mail:*:17379:0:99999:7:::
查看指定行:
root@chengyan-virtual-machine:~# sed -n '3p' /etc/shadow
bin:*:17379:0:99999:7:::
使用正則表達(dá)式:匹配root開頭的行
root@chengyan-virtual-machine:~# sed -n '/^root/p' /etc/shadow
root:$6$lvkzBBp4$EL4M3jGWlhVG73hngVOXVO1o3vtTaLIt7uNrlkC1:19201:0:99999:7:::
查看連續(xù)的行:查看3-6行的內(nèi)容
root@chengyan-virtual-machine:~# sed -n '3,6p' /etc/shadow
bin:*:17379:0:99999:7:::
sys:*:17379:0:99999:7:::
sync:*:17379:0:99999:7:::
games:*:17379:0:99999:7:::
查看文件最后一行內(nèi)容:
root@chengyan-virtual-machine:~# sed -n '$p' /etc/shadow
sshd:*:18964:0:99999:7:::
sed的刪除
刪除指定行并不是真正的刪除,知識(shí)將刪除了的結(jié)果顯示出來(lái),并不是真正的刪除了文件中的內(nèi)容,如果想要真正的刪除文件中的內(nèi)容需要添加選項(xiàng)-i 。
刪除文本中的空行:sed '/^$/d' test.txt
root@chengyan-virtual-machine:~# cat -n test.txt
1
2 1
3 2
4 3
5 4
6
7 6
8 7
9 8
10 9
11
root@chengyan-virtual-machine:~# sed '/^$/d' test.txt
1
2
3
4
6
7
8
9
root@chengyan-virtual-machine:~#
刪除指定行:
root@chengyan-virtual-machine:~# cat -n test.txt
1
2 1
3 2
4 3
5 4
6
7 6
8 7
9 8
10 9
11
root@chengyan-virtual-machine:~# sed '2d' test.txt
2
3
4
6
7
8
9
root@chengyan-virtual-machine:~#
sed的替換
命令格式:sed 指定行 's/需要替換的字符串/替換后的字符串/替換標(biāo)記' 或者[address]s/pattern/replacement/flag
flag標(biāo)記:
-
g :表示要替換所有匹配的行。 -
w :將替換后的結(jié)果保存到文檔。 -
n :1-512,表示指定要替換的字符串出現(xiàn)第幾次時(shí)才進(jìn)行替換。 -
w file :將緩沖區(qū)中的內(nèi)容寫到指定的file文件中。 -
& :用正則表達(dá)式匹配的內(nèi)容進(jìn)行替換。 -
\n :匹配第n個(gè)子串,該子串之前在pattern中用\(\) 指定。 -
\ :轉(zhuǎn)義。
將文件中的test替換為taget:
root@chengyan-virtual-machine:~# cat test1.txt
This is a test file to test replace sed command.
root@chengyan-virtual-machine:~# sed 's/test/taget/g' test1.txt
This is a taget file to taget replace sed command.
root@chengyan-virtual-machine:~#
sed的增加
在第二行下方增加:
root@chengyan-virtual-machine:~# cat test.txt
1
2
3
4
6
7
8
9
root@chengyan-virtual-machine:~# sed '2a ######' test.txt
1
######
2
3
4
6
7
8
9
root@chengyan-virtual-machine:~#
awk
awk原理
awk是一個(gè)強(qiáng)大的文本分析工具,相對(duì)于grep的查找,sed的編輯,awk在其對(duì)數(shù)據(jù)進(jìn)行分析并產(chǎn)生報(bào)告時(shí),顯得尤為強(qiáng)大。簡(jiǎn)單的說(shuō)就是把文件逐行的讀入,以空格為默認(rèn)分隔符將每行切片,切開的部分在進(jìn)行各種分析處理。
awk選項(xiàng)
命令格式:awk [選項(xiàng)] '腳本命令' 文件名
常用選項(xiàng):
-F fs :指定以fs作為輸入行的分隔符,awk命令默認(rèn)分隔符為空格或者制表符。-f file :從腳本文件中讀取awk腳本指令,以取代直接在命令行中輸入指令。-v var=val :在執(zhí)行處理過(guò)程之前,設(shè)置一個(gè)變量var,并給其設(shè)備的初始值為val。
awk的強(qiáng)大在于腳本命令,有兩部分組成,分別是匹配規(guī)則和執(zhí)行命令。
匹配規(guī)則{執(zhí)行命令}
root@chengyan-virtual-machine:~# cat test.txt
1
2
3
4
6
7
8
9
root@chengyan-virtual-machine:~# awk '/^$/{print "Blank line"}' test.txt
Blank line
Blank line
Blank line
root@chengyan-virtual-machine:~#
其中,/^$/ 是一個(gè)正則表達(dá)式,功能是匹配文本中的空白行,同時(shí)可以看到,執(zhí)行命令使用的是print命令,此命令的功能是將指定的文本進(jìn)行輸出。
awk的主要特性之一就是處理文本文件中數(shù)據(jù)的能力,它會(huì)自動(dòng)給一行中的每個(gè)數(shù)據(jù)元素分配一個(gè)變量。默認(rèn)情況下,awk會(huì)將如下變量分配給它在文本行中發(fā)現(xiàn)的數(shù)據(jù)字段。
- $0代表整個(gè)文本行。
- $1代表文本行中的第一個(gè)數(shù)據(jù)字段。
- $2代表文本行中的第二個(gè)數(shù)據(jù)字段。
- $n代表文本行中的第n個(gè)數(shù)據(jù)字段。
awk默認(rèn)的字段分割符是任意的空白字符,在文本行中,每個(gè)數(shù)據(jù)字段都是通過(guò)子彈分割符換分的。awk在讀取一行文本時(shí),會(huì)用預(yù)定的字段分隔符換分每個(gè)數(shù)據(jù)字段。
root@chengyan-virtual-machine:~# cat data.txt
One line of test txt.
Two lines of test txt.
Three lines of test text.
root@chengyan-virtual-machine:~# awk '{print $1}' data.txt
One
Two
Three
root@chengyan-virtual-machine:~#
上面只用了$1 字段變量來(lái)表示“僅顯示每行文本的第一個(gè)數(shù)據(jù)字段”。要讀取采用了其他字段分隔符的文件,可以用-F 選項(xiàng)手動(dòng)指定。
awk允許將多條命令組合稱為一個(gè)正常的程序。要在命令行上的程序腳本中使用多條命令,只要在命令之間放個(gè)分號(hào)即可。
root@chengyan-virtual-machine:~# echo "My name is Rich" | awk '{$4="Christine";print $0}'
My name is Christine
root@chengyan-virtual-machine:~# awk '{
> $4="Christine";
> print $0
> }'
My name is Rich
My name is Christine
His name is wanghao
His name is Christine
當(dāng)用了起始的單引號(hào)后,bash shell會(huì)使用> 來(lái)提示輸入更多數(shù)據(jù),可以在每行加一條命令,知道輸入了結(jié)尾的單引號(hào)。因?yàn)闆](méi)有在命令行中指定文件名,awk程序需要用戶輸入獲得數(shù)據(jù),因此當(dāng)運(yùn)行這個(gè)程序的時(shí)候,會(huì)一直等待用戶輸入文本,此時(shí)如果要退出程序,只需要輸入CTRL+D即可。
root@chengyan-virtual-machine:~# cat awk.sh
{print $1"'s home directory is " $6}
root@chengyan-virtual-machine:~# awk -F : -f awk.sh /etc/passwd
root's home directory is /root
daemon's home directory is /usr/sbin
bin's home directory is /bin
sys's home directory is /dev
sync's home directory is /bin
games's home directory is /usr/games
man's home directory is /var/cache/man
在腳本文件中,可以指定多條命令,只要一條命令放在一行就行.
關(guān)鍵字
BEGIN
awk中還可以指定腳本命令運(yùn)行的時(shí)機(jī),默認(rèn)情況下,awk會(huì)從輸入中讀取一行文本,然后針對(duì)該行的數(shù)據(jù)執(zhí)行程序腳本,但有時(shí)可能需要在處理數(shù)據(jù)前運(yùn)行一些腳本命令,這就需要使用BEGIN關(guān)鍵字。
BEGIN關(guān)鍵字會(huì)強(qiáng)制awk在讀取數(shù)據(jù)前執(zhí)行該關(guān)鍵字后指定的腳本命令。
root@chengyan-virtual-machine:~# awk 'BEGIN{print "The data file contents:"}
> {print $0}' data.txt
The data file contents:
One line of test txt.
Two lines of test txt.
Three lines of test text.
root@chengyan-virtual-machine:~#
這個(gè)腳本命令分為兩部分,BEGIN部分的腳本指令會(huì)在awk命令處理函數(shù)前運(yùn)行,而真正用來(lái)處理數(shù)據(jù)的是第二段腳本命令。
END
END關(guān)鍵字允許指定一些腳本命令,awk會(huì)在讀取完數(shù)據(jù)后執(zhí)行。
root@chengyan-virtual-machine:~# awk 'BEGIN{print "The data file contents:"}
{print $0}
END{print "End of file"}' data.txt
The data file contents:
One line of test txt.
Two lines of test txt.
Three lines of test text.
End of file
root@chengyan-virtual-machine:~#
變量
在awk腳本程序中,支持使用變量來(lái)存取值,awk支持兩種不同類型的變量,即內(nèi)建變量和自定義變量。
內(nèi)建變量是awk本身就創(chuàng)建好的,用戶可以直接使用的變量,這些變量用來(lái)存放處理數(shù)據(jù)文件中的某些字段和記錄的信息。自定義變量是awk支持用戶自己創(chuàng)建的變量。
常見的內(nèi)建變量包括數(shù)據(jù)字段變量($0,$1,$2,.... )和其他變量。
字符和記錄分隔符變量:
FIELDWIDTHS :由空格分割的一列數(shù)字,定義了每個(gè)數(shù)據(jù)字段的確切寬度。FNR :當(dāng)前輸入文檔的記錄編號(hào),常在有多個(gè)輸入文檔時(shí)使用。NR :輸入流的當(dāng)前記錄編號(hào)。FS :輸入字段分隔符。RS :輸入記錄分隔符,默認(rèn)為換行符\n。OFS :輸出字段分隔符,默認(rèn)為空格。ORS :輸出字段分隔符,默認(rèn)為換行符\n。
環(huán)境信息變量:
ARGC :命令行參數(shù)個(gè)數(shù)。ARGIND :當(dāng)前文件在ARGC中的位置。ARGV :包含命令行參數(shù)的數(shù)組。CONVFMT :數(shù)字的轉(zhuǎn)換格式,默認(rèn)值為%.6g。ENVIRON :當(dāng)前shell環(huán)境變量及其值組成的關(guān)聯(lián)數(shù)組。ERRNO :當(dāng)前讀取或關(guān)閉輸入文件發(fā)生錯(cuò)誤時(shí)的系統(tǒng)錯(cuò)誤號(hào)。FILENAME :當(dāng)前輸入文檔的名稱。FNR :當(dāng)前數(shù)據(jù)文件中的數(shù)據(jù)行數(shù)。IGNORECASE :設(shè)成非0值時(shí),忽略awk命令中出現(xiàn)的字符串的字符串大小。NF :數(shù)據(jù)文件中的字段總數(shù)。OFMT :數(shù)字的輸出格式,默認(rèn)值為%.6g。RLENGTH :由match函數(shù)所匹配的子字符串的長(zhǎng)度。TSTART :由match函數(shù)所匹配的子字符串的起始位置。
FS/OFS
變量FS和OFS定義了awk如何處理數(shù)據(jù)流中的數(shù)據(jù)字段。
root@chengyan-virtual-machine:~# cat data.txt
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35
root@chengyan-virtual-machine:~# awk 'BEGIN{FS=",";OFS="-"}{print $1,$2,$3}' data.txt
data11-data12-data13
data21-data22-data23
data31-data32-data33
root@chengyan-virtual-machine:~# awk 'BEGIN{FS=",";OFS="--"}{print $1,$2,$3}' data.txt
data11--data12--data13
data21--data22--data23
data31--data32--data33
root@chengyan-virtual-machine:~#
FIELDWIDTHS
FIELDWIDTHS變量允許用戶不依靠字段分隔符來(lái)讀取記錄,數(shù)據(jù)如果沒(méi)有設(shè)置分隔符,而是放在特定列中,這種情況下,必須設(shè)定FIELDWIDTHS變量來(lái)匹配數(shù)據(jù)在記錄中的位置。一旦設(shè)置了FIELDWIDTH變量,awk就會(huì)忽略FS變量,并根據(jù)提供的字段寬度來(lái)計(jì)算字段。
root@chengyan-virtual-machine:~# cat data1.txt
1005.3247596.37
115-2.349194.00
05810.1298100.1
root@chengyan-virtual-machine:~# awk 'BEGIN{FIELDWIDTHS="3 5 2 5"}{print $1,$2,$3,$4}' data1.txt
1005.3247596.37
115-2.349194.00
05810.1298100.1
root@chengyan-virtual-machine:~#
一旦設(shè)置了FIELWIDTHS變量的值,就不能在改變了,所以并不適用于變長(zhǎng)的字段。
RS/ORS
變量RS和ORS定義了awk程序如何處理數(shù)據(jù)流中的字段,默認(rèn)情況下,awk將RS和ORS設(shè)為換行符。默認(rèn)的RS值標(biāo)明,輸入數(shù)據(jù)流中的每行新文本都是一條新紀(jì)錄。
root@chengyan-virtual-machine:~# cat data2.txt
Riley Mullen
123 Main Street
Chicago,IL 60601
(312)555-1234
Frank Wiliams
456 Oak Street
Indianapolis,IN 46201
(317)555-9876
Haley Snell
4231 Elm Street
Detroit,MI 48201
(313)555-4938
root@chengyan-virtual-machine:~# awk 'BEGIN{FS="\n";RS=""}{print $1,$4}' data2.txt
Riley Mullen (312)555-1234
Frank Wiliams (317)555-9876
Haley Snell (313)555-4938
root@chengyan-virtual-machine:~#
FNR/NR
FNR變量含有當(dāng)前數(shù)據(jù)文件中已處理過(guò)的記錄數(shù),NR變量則含有已處理過(guò)的記錄總數(shù)。
root@chengyan-virtual-machine:~# cat data.txt
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35
root@chengyan-virtual-machine:~# awk '
> BEGIN{FS=","}
> {print $1, "FNR="FNR, "NR="NR}
> END{print "There were",NR,"records processed"}' data.txt data.txt
data11 FNR=1 NR=1
data21 FNR=2 NR=2
data31 FNR=3 NR=3
data11 FNR=1 NR=4
data21 FNR=2 NR=5
data31 FNR=3 NR=6
There were 6 records processed
root@chengyan-virtual-machine:~#
可以發(fā)現(xiàn),當(dāng)使用一個(gè)數(shù)據(jù)文件作為輸入時(shí),F(xiàn)NR和NR的值相同的,如果多個(gè)文件同時(shí)作為輸入時(shí),F(xiàn)NR的值會(huì)在處理每個(gè)數(shù)據(jù)文件時(shí)被重置,而NR的值則會(huì)繼續(xù)計(jì)數(shù)知道處理完所有的數(shù)據(jù)文件。
|