Linux bash總結(二) 高級部分(適合初學者學習和非初學者參考) (持續更新中...)
版本號 | 說明 | 作者 | 日期 |
1.0 | 添加awk和sed的說明 | Sky Wang | 2013/05/31 |
1.1 | (01) 添加正則表達式(第3部分) (02) 修改awk中錯誤內容 |
Sky Wang | 2013/06/05 |
本文主要通過實例對bash中需要用到的一些高級工具(如awk、sed、...)進行說明。學習的時候,請以“應用實例”為中心,以其它內容為參考進行學習。如果遇到文章中未講解的內容,可以通過man去查閱用法。
轉載請注明出處:Linux bash總結(二) 高級部分(適合初學者學習和非初學者參考) (持續更新中...)
第一部分 awk工具
本章主要通過awk的一些應用實例,來說明awk的相關語法。這樣,更利於我們進行理解;所以,閱讀本章時,請以“應用實例”為中心進行閱讀,其它部分是參考內容。
1 awk介紹
awk是一種用於處理文本的編程語言工具。awk本身就是linux下的一個工具,既可以單獨使用,也可以嵌入到bash中。
awk語言的最基本功能是在文件或字符串中基於指定規則瀏覽和抽取信息。 awk抽取信息后,才能進行其他文本操作。完整的 awk腳本通常用來格式化文本文件中的信息。
2 awk環境變量
3 awk條件操作符
4 awk字符串操作
5 正則表達式中常用類
6 awk應用實例
首先建立一個123.txt,添加任意文本,然后進行以下練習。
(01), 輸出文件全部文本
$ awk '{print $0}' 123.txt
說明:
{}:表示一段awk命令。
print:輸出指令。
$0:當前行的全部文本。
awk工具操作文件時,是以行為單位,逐步對每行進行操作。拿本例來說{print $0},意味着“對每一行都執行print $0操作,即輸出每一行的全部文本”。
$N:當N>1時,$N表示當前行的第N段;每一行中以FS(默認值是空格)來分段。
(02), 輸出"ls -l"中每行的field1、field9
$ ls -l | awk '{printf("%s %s\n", $1, $9)}'
說明:
|:管道符號。表示將“前面指令的輸出”作為“后面指令的輸入”,即將“ls -l”的輸出作為“awk”的輸入。
printf:輸出指令。它的使用方法和C語言中printf的使用方法一樣。
$1:該行的第1段。
$9:該行的第9端。
(03), 在上一題的基礎上添加功能:第一,輸出每一行的行號和該行所包括的域的總數。第二,第1行和最后一行輸出提示語
$ ls -l | awk 'BEGIN{printf("----begin----\n")} {printf("Line-%3d Field-%d : %s %s\n", NR, NF, $1, $9)} END{printf("----end----\n")}'
說明:
BEGIN:表示在文本進行操作之前進行的工作。
END:表示在對文本的所有行都處理完畢之后前進行的工作。
在awk中,請盡量使用{}來進行區分指令段,{}可以嵌套使用!這樣做的好處寫出的腳本不容易出錯,而且可讀性更強!
(04), 輸出"ls -l"中文件(夾)名字包括數字的完整信息
$ ls -l | awk '{if($9 ~ /[[:digit:]]/) {print $0}}'
說明:
$9 ~ /[[:digit:]]/ : 表示能夠匹配數字的“第一行的第9段”。
(05), 輸出"ls -l"中非文件夾的完整信息
$ ls -l | awk '{if($1 !~ /^d/) {print $0}}'
說明:
^d : 以d開頭的。^表示起始位。此外,$表示結束位。如d$,表示以d結尾的。
(06), 找到"ls -l"中文件(夾)名字的長度大於10的行,然后輸出其完整信息。
$ ls -l | awk '{if(length($9) > 10) {print $0}}'
(07), 如何給文本的每一行添加行號?
$ awk '{printf("%03d %s\n",NR, $0)}' ori.txt > dst.txt
(08), 打印字段數大於3的行的總數
$ awk 'BEGIN{COUNT=0}; {if(NF>3) COUNT++}; END{printf("COUNT=%d\n", COUNT)}' ori.txt
(09), 將文本中的各行合並一行,中間用“|”分割
$ awk 'BEGIN{ORS="|"}{print $0 }END{print "\n"}' ori.txt > dst.txt
說明:
ORS:表示記錄分割符,每條記錄表示每行。ORS默認值為換行符。
(10), 將文本中空格換成換行符
$ awk 'BEGIN{FS=" ";OFS="\n"}{print $1 }END{print "\n"}' ori.txt > dst.txt
(11), 將3行合並成一行,並輸入行號
$ awk 'BEGIN{ORS="";i=0}{ j=1; while(j<=NF){ if(i%3==0){printf("%02d ",i/3+1)}; printf("%s ",$j); i++; j++; if(i%3==0){print "\n"} }} END{print "\n"}' ori.txt > dst.txt
第二部分 sed工具
和awk一樣,本章主要通過實例對sed進行介紹。這樣,更利於我們進行理解;所以,閱讀本章時,請以“應用實例”為中心進行閱讀,其它部分是參考內容。
1 sed介紹
sed是一個非交互性文本流編輯器。和awk一樣,它是個獨立的工具,當然也可以和bash聯合使用。
它可以隨意編輯文件或標准輸入,對它們進行編輯、刪除。它能一次性處理所有改變,對用戶來講,十分高效。sed編輯文件或標准輸入時,編輯的是它們的拷貝;也就是說,不會改變原始的文件。若需要保存修改,可以通過重定向操作符>>、>>>,或者在利用sed的寫入參數。
2 基本格式
sed [選項] 輸入文件
-n 不打印;sed不寫編輯行到標准輸出,缺省為打印所有行(編輯和未編輯)。
-p 命令可以用來打印編輯行。
-c 下一命令是編輯命令。使用多項編輯時加入此選項。如果只用到一條 sed命令,此選項無用,但指定它也沒有關系。
-e 追加執行腳本
-f 如果正在調用 sed腳本文件,使用此選項。
3 使用sed在文件中定位文本的方式
如下表:
4 sed編輯命令
如下表:
5 應用實例
首先建立一個123.txt,添加任意文本,然后進行以下練習。
(01), 輸出文件第5行
$ sed -n '5p' 123.txt
說明:
-n表示默認不輸出任何內容。5p表示輸出第5行:5表示第5行,p表示輸出。
(02), 輸出文件除1-3行之外的行
$ sed -n '1,3!p' 123.txt
說明:
"1,3"表示輸出范圍是第1-3行; "1,3!"表示輸出范圍是除第1-3行之外。
'1,$p'表示輸出全部行,因為$表示最后一行。
(03), 輸出"ls -l"結果中的第1-3行
$ ls -l |sed -n '1,3p'
說明:
|是管道符號,表示將ls -l的輸出作為sed的輸入。
(04), 輸出匹配“the”的行
$ sed -n '/the/p' 123.txt
說明:
/the/表示匹配the的行
(05), 輸出匹配“the”的行,並且輸出每行行號
$ sed -n -e '/the/p' -e '/the/=' 123.txt
說明:
-e表示對每行進行多重編輯,多重編輯的每一個命令前都需要添加-e。
本例中,-e '/the/p'打印匹配the的行;-e '/the/='表示輸出匹配the的行的行號。
(06), 刪除匹配“the”的行
$ sed '/the/d' 123.txt
說明:
d表示刪除。
(07), 刪除匹配“the”的行;然后輸出刪除操作之后的所有行,並輸出每行行號
$ sed '/the/d' 123.txt | sed -n -e '1,$p' -e '1,$='
說明:
sed '/the/d' 123.txt :得到了刪除“the”之后的行
| :管道符號。意味着前面的輸出作為后面的輸入
sed -n -e '1,$p' -e '1,$=' :表示輸出全部行之后,在輸出每行行號
(08), 在每一行前面插入2行文本,第一行是line1,第2行是line2
$ sed '1,$iline1\nline2' 123.txt
說明:
1,$i表示第一行到最后一行的每一行都執行插入操作。
line1\nline2表示插入的文本,其中\n轉義之后表示“換行”符號。
(09), 在最后一行后面插入1行文本,內容是end
$ sed '$aend' 123.txt
說明:
$表示最后一行,a表示在文本后插入,end是插入的內容
(10), 將“this”全部替換成“that”
$ sed 's/this/that/g' 123.txt
說明:
[ address[,address ] ] s / pattern-to-find / replacement-pattern/[gpwn]
s 表示替換操作。查詢pattern-to-find,成功后用replacement-pattern替換它。
替換選項如下:
g 缺省情況下只替換每行的第一次匹配,g表示替換每行的所有匹配。
p 缺省sed將所有被替換行寫入標准輸出,加p選項將使-n選項無效。-n選項不打印輸出結果。
w 后接“文件名”,表示將輸出定向到一個文件。
(11), 將“this”全部替換成“this boy”
$ sed 's/this/this boy/g' 123.txt 或 $ sed 's/this/boy &/g' 123.txt
說明:
sed 's/this/boy &/pg' 123.txt中&表示附加修改(即在原始內容的基礎上添加內容)。
&表示匹配的內容。即,boy &等價於boy this
(12), 去掉空白行后另存文件
$ sed '/^$/d' 123.txt > 456.txt 或 $ sed '/^$/c\' 123.txt > 456.txt
說明:
/^$/表示空白行:^表示開啟,$表示結尾,開始和結尾之間沒有任何內容,即是空白行。
c\表示修改。
(13), 去掉文件擴展名
$ echo "hello.txt"| sed 's/.txt//g'
(14), 添加文件擴展名
$ echo "hello"| sed 's/$/.txt/g'
(15), 刪除文本中每一行的第2個字符
$ sed 's/.//2' ori.txt > dst.txt
(16), 刪除文本中每一行的倒數第2個字符
$ sed 's/\(.\)\(.\)$/\2/' ori.txt > dst.txt
#說明:考察了sed中"\( \)"的含義和用法
(17), 刪除每一行的第2個單詞
$ sed 's/\([[:alpha:]]\+\)\(\ \)\([[:alpha:]]\+\)*/\1/' ori.txt > dst.txt
(18), 隔行刪除
$ sed '0~2 d' ori.txt > dst.txt
第三部分 正則表達式和grep
本章主要通過一些應用實例,來對正則表達式進行說明。
1 正則表達式
正則表達式就是字符串的表達式。它能通過具有意義的特殊符號表示一列或多列字符串。
grep是linux系統下常用的正則表達式工具,可以使用grep來檢索文本等輸入流的字符串。
2 正則表達式特殊符號
參考下面表格
3 grep表達式
基本格式
grep [OPTIONS] PATTERN [FILE...]
格式說明
PATTERN : 匹配模式。可以是字符串,也可以是正則表達式。
[FILE...] : 是grep搜索的文件(集)
[OPTIONS] : 是grep的選項。常用的選項有以下選項。
-c : 只輸出匹配行的計數。
-I : 不區分大 小寫(只適用於單字符)。
-h : 查詢多文件時不顯示文件名。
-l : 查詢多文件時只輸出包含匹配字符的文件名。
-n : 顯示匹配行及 行號。
-s : 不顯示不存在或無匹配文本的錯誤信息。
-v : 顯示不包含匹配文本的所有行。
-r : 當FILE中包含文件夾名時,遍歷該文件夾的所有子目錄;默認情況下,不會遍歷子目錄。
4 應用實例
下面以input.txt為例,對grep進行說明。input.txt的文本內容如下:
"Open Source" is a good mechanism to develop programs. apple is my favorite food. Football game is not use feet only. this dress doesn't fit me. However, this dress is about $ 3183 dollars.^M GNU is free air not free beer.^M Her hair is very beauty.^M I can't finish the test.^M Oh! The soup taste good.^M motorcycle is cheap than car. This window is clear. the symbol '*' is represented as start. Oh! My god! The gd software is a library for drafting programs.^M You are the best is mean you are the no. 1. The world <Happy> is the same with "glad". I like dog. google is the best tools for search keyword. goooooogle yes! go! go! Let's go
(01), 查找包含“the”的行,並顯示行號。
$ grep -n "the" input.txt
說明:-n表示顯示“行號”
(02), 不區分大小寫,查找包括“the”的行,並顯示行號。
$ grep -in "the" input.txt
說明:-n表示顯示“行號”;-i表示不區分大小寫,即ignore大小寫。
(03), 查找不包括“the”的行,統計行數。
$ grep -cv "the" input.txt
說明:-c表示統計(count);-v表示不匹配的項。
(04), 查找“當前目錄”及其“所有子目錄”中包含“the”的文件,並顯示“the”在其中的行號。
$ grep -rn "the" .
說明:-r表示遞歸查找;-n表示顯示行號。
(05), 查找匹配“t?st”的項,其中?為任意字符。
$ grep -n "t.st" input.txt
說明:.表示匹配任意字符
(06), 查找包含數字的行
$ grep -n "[0-9]" input.txt 或 $ grep -n "[[:digit:]]" input.txt
說明:[0-9]表示0-9之間的一個數字;[[:digit:]]也表示0-9之間的一個數字
(07), 查找以the開頭的行
$ grep -n "^the" input.txt
說明:"^the"表示以the開頭
(08), 查找以小寫字母結尾的行。
$ grep -n "[a-z]$" input.txt
說明:[a-z]表示一個小寫字母,$表示結束符;[a-z]$表示以小寫字母結束的項。
(09), 查找空白行。
$ grep -n "^$" input.txt
說明:^表示開頭,如^t表示以字母t開頭;$表示結尾,如e$表示以e結尾。^$表示空白行。
(10), 查找以字母g開頭的單詞
$ grep -n "\<g" input.txt
說明:\<表示單詞的開始,\<g表示以g開始的單詞。
(11), 查找字符串為go的單詞。注意:不能包括goo,good等字符串
$ grep -n "\<go\>" input.txt
說明:\<表示單詞的開始,\>表示單詞結尾。\<go\>表示以字母g開頭,以字母o結尾。
(12), 查找包括2-5個字母o的行。
$ grep -n "o\{2,5\}" input.txt
說明:pattern\{n,m\}表示n到m個pattern。o\{2,5\}表示2-5個字母o。
(13), 查找包括2個以上字母o(包括2個)的行。
$ grep -n "ooo*" input.txt 或 $ grep -n "oo\+" input.txt 或 $ grep -n "o\{2,\}" input.txt
說明:
ooo*: 前面兩個oo表示匹配2個字母o,后面的o*表示匹配0到多個字母o。
oo\+: 第一個字母o表示匹配單個字母o;最后的“o\+”一起發揮作用,其中,\+是轉義后的+,表示1到多個;而o\+表示1到多個字母o。
pattern\{n,\}表示多於n個pattern。o\{2,\}表示多於2個字母o。
4 egrep
4.1 egrep說明
egrep是擴展的grep,即它的功能比grep更多一些。"egrep"等價於"grep -e"。
egrep相比與grep,支持括號“()”以及操作符“|”(表示或)。
4.2 egrep應用實例
仍然以上面的input.txt為輸入文本進行說明
(01), 查找包含the或者this的行
$ egrep -n "the|this" input.txt
說明:-n表示輸出匹配項的行號,"the|this"表示包括the或者包括this的項。
(02), 查找包含the或者this的行
$ egrep -vn "(the|this)" input.txt
說明:-n表示輸出匹配項的行號,"the|this"表示包括the或者包括this的項;-v表示匹配的對立面。即 -v "the|this"表示既不包括the又不包括this的項。
關於Linux bash基礎部分,請參考:Linux bash總結(一) 基礎部分(適合初學者學習和非初學者參考)