|
Linux三劍客是指的grep、sed、awk三個命令,grep主打查找功能,sed主要是編輯,awk主要是分割處理。
grep
grep是global regular expressions print的縮寫。grep命令能夠在一個或者多個文件中搜索某一特定的字符模式,此模式可以是單一的字符、字符串、單詞或句子。grep可以在文本中查找指定的字符串,是linux中最常用的文本處理工具之一。正則表達式的通配符如下:
* : 將匹配0個或者多個字符。. :將匹配任何一個字符,且只能是一個字符。[xyz] :匹配方括號中的任意一個字符。[^xyz]:匹配方括號中的任意一個字符。^ : 鎖定行的開頭。$ :鎖定行的結尾。? :匹配前面的子表達式0次或者1次。+ :匹配前面的子表達式1次或者多次。| : 匹配于|符號前或后的正則表達式。{n,m} :最少匹配n次,最多匹配m次和BRE的區(qū)別是不需要加\。
在基本的正則表達式中,使用通配符原本的意思,需要添加\作為轉義字符。
grep命令用來在每一個文件搜索特定的模式,當使用grep時,包含指定字符模式的每一行內容,都會被打印到屏幕上,但是使用grep命令并不改變文件中的內容。
grep命令格式:grep [選項] 模式 文件名
這里的模式,要么是字符串,要么是正則表達式。常用的選項如下表。
-
-c:僅列出文件中包含模式的行數,即匹配到的總行數。 -
-i:忽略模式中的字母大小寫。 -
-l:列出帶有匹配行的文件名。 -
-n:在每一行的最前面列出行號。 -
-v:列出沒有匹配模式的行。 -
-w:把代表式當做一個完整的單字符來搜尋,忽略哪些部分匹配的行。 -
-color=auto或者-color:表示對匹配到的文本著色顯示。 -
-o:只顯示符號條件的字符串,但是不整行顯示,每個符號條件的字符串單獨顯示一行。 -
-w:匹配整個單詞,如果是字符串中包含這個單詞,則不做匹配。
如果是搜索多個文件,grep命令的搜索結果只顯示文件中發(fā)現匹配模式的文件名,如果搜索單個文件,grep命令的結果將顯示每一個包含匹配模式的行。
sed原理
sed是一種流編輯器,流編輯器會在編輯器處理數據之前基于預先提供一組規(guī)則來編輯數據流。sed編輯器可以根據命令來處理數據流中的數據,這些命令要么從命令行中輸入,要么存儲在一個命令文本中。
sed是操作、過濾和轉換文本內容的強大工具,常用功能增刪改查,過濾,取行。
sed命令的格式如下:sed [options] [sed-commands] [input-file]
- options常用的有:
-n ---- 抑制默認輸出,-e ---- 執(zhí)行多條編輯命令, -i ---- 直接在源文件中修改。 - sed-commands:既可以是單個sed命令,也可以是多個sed命令組合。
- input-file:可選項,sed還可以從標準輸出如管道獲取輸入。
sed是從文件或者管道中讀取一行,放在模式空間中,進行處理,處理完輸出一行,在讀取一行,再處理一行。模式空間是sed內部的臨時緩存,用于存放讀取到的內容。
sed可以對單行或多行進行處理,如果在sed命令前面不指定地址范圍,那么默認會匹配所有行。
sed流程
sed的工作流程主要包括讀取、執(zhí)行和顯示三個過程。
讀取流程:sed從輸入流(文件、管道、標準輸入)中讀取一行內容并存在到臨時的緩沖區(qū)中(又稱為模式空間)。
執(zhí)行流程:默認情況下,所有的sed命令都在模式空間中順利地執(zhí)行,除非指定了行的地址,否則sed命令,將會在所有的行上依次執(zhí)行。
顯示流程:發(fā)送修改后的內容到輸出流。在發(fā)送數據后,模式空間將會被清空,在所有的文件內容都被完成處理之前,上述過程被反復執(zhí)行,直至內容被處理完。
sed選項
sed命令格式:
sed -e '操作' 文件1 文件2sed -n -e '操作' 文件1 文件2sed -f 腳本文件 文件1 文件2sed -e -i '操作' 文件1 文件2
常用選項:
-e或--expression:表示用指定命令來處理輸入的文本文件,只有一個操作命令時可以省略,一般在執(zhí)行多個操作命令使用。-f或--file:表示用指定腳本文件來處理輸入的文本文件。-h或--help:顯示幫助。-n或s --quiet:禁止sed編輯器輸出,但可以與p命令一起使用完成輸出。-i:直接修改文本文件。-r,-E:使用擴展正則表達式-s:將多個文件視為獨立文件,而不是單個連續(xù)的長文件流。
常用操作:
s:替換指定字符(替換)。d:刪除指定的行(刪除)。a:在指定的行上一行增加一行指定內容(增加)。i:在指定的上一行插入一行指定內容(插入)。c:將選定行內容替換為指定內容(替換)。y:字符轉換,轉換之后的字符長度必須相同。p:打印,如果同時指定行,表示打印指定行,如果不指定行,則表示打印所有內容;如果有非打印字符,則以Ascii碼輸出。通常與_n選項一起使用。=:打印行號。l:答應數據流中的文本和不可打印的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:::
使用正則表達式:匹配root開頭的行
root@chengyan-virtual-machine:~# sed -n '/^root/p' /etc/shadow
root:$6$lvkzBBp4$EL4M3jGWlhVG73hngVOXVO1o3vtTaLIt7uNrlkC1:19201:0:99999:7:::
查看連續(xù)的行:查看3-6行的內容
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:::
查看文件最后一行內容:
root@chengyan-virtual-machine:~# sed -n '$p' /etc/shadow
sshd:*:18964:0:99999:7:::
sed的刪除
刪除指定行并不是真正的刪除,知識將刪除了的結果顯示出來,并不是真正的刪除了文件中的內容,如果想要真正的刪除文件中的內容需要添加選項-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/需要替換的字符串/替換后的字符串/替換標記'或者[address]s/pattern/replacement/flag
flag標記:
-
g:表示要替換所有匹配的行。 -
w:將替換后的結果保存到文檔。 -
n:1-512,表示指定要替換的字符串出現第幾次時才進行替換。 -
w file:將緩沖區(qū)中的內容寫到指定的file文件中。 -
&:用正則表達式匹配的內容進行替換。 -
\n:匹配第n個子串,該子串之前在pattern中用\(\)指定。 -
\:轉義。
將文件中的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是一個強大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數據進行分析并產生報告時,顯得尤為強大。簡單的說就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分在進行各種分析處理。
awk選項
命令格式:awk [選項] '腳本命令' 文件名
常用選項:
-F fs:指定以fs作為輸入行的分隔符,awk命令默認分隔符為空格或者制表符。-f file:從腳本文件中讀取awk腳本指令,以取代直接在命令行中輸入指令。-v var=val:在執(zhí)行處理過程之前,設置一個變量var,并給其設備的初始值為val。
awk的強大在于腳本命令,有兩部分組成,分別是匹配規(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:~#
其中,/^$/是一個正則表達式,功能是匹配文本中的空白行,同時可以看到,執(zhí)行命令使用的是print命令,此命令的功能是將指定的文本進行輸出。
awk的主要特性之一就是處理文本文件中數據的能力,它會自動給一行中的每個數據元素分配一個變量。默認情況下,awk會將如下變量分配給它在文本行中發(fā)現的數據字段。
- $0代表整個文本行。
- $1代表文本行中的第一個數據字段。
- $2代表文本行中的第二個數據字段。
- $n代表文本行中的第n個數據字段。
awk默認的字段分割符是任意的空白字符,在文本行中,每個數據字段都是通過子彈分割符換分的。awk在讀取一行文本時,會用預定的字段分隔符換分每個數據字段。
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字段變量來表示“僅顯示每行文本的第一個數據字段”。要讀取采用了其他字段分隔符的文件,可以用-F選項手動指定。
awk允許將多條命令組合稱為一個正常的程序。要在命令行上的程序腳本中使用多條命令,只要在命令之間放個分號即可。
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
當用了起始的單引號后,bash shell會使用>來提示輸入更多數據,可以在每行加一條命令,知道輸入了結尾的單引號。因為沒有在命令行中指定文件名,awk程序需要用戶輸入獲得數據,因此當運行這個程序的時候,會一直等待用戶輸入文本,此時如果要退出程序,只需要輸入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
在腳本文件中,可以指定多條命令,只要一條命令放在一行就行.
關鍵字
BEGIN
awk中還可以指定腳本命令運行的時機,默認情況下,awk會從輸入中讀取一行文本,然后針對該行的數據執(zhí)行程序腳本,但有時可能需要在處理數據前運行一些腳本命令,這就需要使用BEGIN關鍵字。
BEGIN關鍵字會強制awk在讀取數據前執(zhí)行該關鍵字后指定的腳本命令。
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:~#
這個腳本命令分為兩部分,BEGIN部分的腳本指令會在awk命令處理函數前運行,而真正用來處理數據的是第二段腳本命令。
END
END關鍵字允許指定一些腳本命令,awk會在讀取完數據后執(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腳本程序中,支持使用變量來存取值,awk支持兩種不同類型的變量,即內建變量和自定義變量。
內建變量是awk本身就創(chuàng)建好的,用戶可以直接使用的變量,這些變量用來存放處理數據文件中的某些字段和記錄的信息。自定義變量是awk支持用戶自己創(chuàng)建的變量。
常見的內建變量包括數據字段變量($0,$1,$2,....)和其他變量。
字符和記錄分隔符變量:
FIELDWIDTHS:由空格分割的一列數字,定義了每個數據字段的確切寬度。FNR:當前輸入文檔的記錄編號,常在有多個輸入文檔時使用。NR:輸入流的當前記錄編號。FS:輸入字段分隔符。RS:輸入記錄分隔符,默認為換行符\n。OFS:輸出字段分隔符,默認為空格。ORS:輸出字段分隔符,默認為換行符\n。
環(huán)境信息變量:
ARGC:命令行參數個數。ARGIND:當前文件在ARGC中的位置。ARGV:包含命令行參數的數組。CONVFMT:數字的轉換格式,默認值為%.6g。ENVIRON:當前shell環(huán)境變量及其值組成的關聯數組。ERRNO:當前讀取或關閉輸入文件發(fā)生錯誤時的系統(tǒng)錯誤號。FILENAME:當前輸入文檔的名稱。FNR:當前數據文件中的數據行數。IGNORECASE:設成非0值時,忽略awk命令中出現的字符串的字符串大小。NF:數據文件中的字段總數。OFMT:數字的輸出格式,默認值為%.6g。RLENGTH:由match函數所匹配的子字符串的長度。TSTART:由match函數所匹配的子字符串的起始位置。
FS/OFS
變量FS和OFS定義了awk如何處理數據流中的數據字段。
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變量允許用戶不依靠字段分隔符來讀取記錄,數據如果沒有設置分隔符,而是放在特定列中,這種情況下,必須設定FIELDWIDTHS變量來匹配數據在記錄中的位置。一旦設置了FIELDWIDTH變量,awk就會忽略FS變量,并根據提供的字段寬度來計算字段。
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:~#
一旦設置了FIELWIDTHS變量的值,就不能在改變了,所以并不適用于變長的字段。
RS/ORS
變量RS和ORS定義了awk程序如何處理數據流中的字段,默認情況下,awk將RS和ORS設為換行符。默認的RS值標明,輸入數據流中的每行新文本都是一條新紀錄。
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變量含有當前數據文件中已處理過的記錄數,NR變量則含有已處理過的記錄總數。
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ā)現,當使用一個數據文件作為輸入時,FNR和NR的值相同的,如果多個文件同時作為輸入時,FNR的值會在處理每個數據文件時被重置,而NR的值則會繼續(xù)計數知道處理完所有的數據文件。
|