1、查找文件命令傳統上分爲三種:grep、egrep、fgrep正則表達式
三種命令的區別在於:fgrep是惟一支持並行匹配多個字符串的版本;而grep與egrep只能匹配單個正則表達式。數據庫
grep默認行爲模式: grep == grep -F fgrep == grep -F egrep == grep -Eapache
2、說到grep就不得不提起正則:less
這裏特指符合POSIX標準的正則表達式,它符合如下兩個特色:工具
1 特定於locale的字符序列順序和等價字符命令行
2 沒必要關心繫統底層的字符集設計
正式講正則以前插播一小段精品廣告,他們是關於sed(stream editor)、awk、Perl、Tcl、more/less等,這些工具程序都有一個共同點,就是都沿用了某一種正則表達式形式來強化自己的功能。xml
首先講到的是三類特殊符號:排序
1 排序[..ch..]ip
2 等價[=e=]
3 字符集[:xxx:]
另外一個是後向引用,他在尋找重複字以及匹配引號時特別好用: \(["']\).*\1 匹配以單引號或雙引號括起來的字
區間表達式:將一個或兩個數字,放在\{與\}之間,有三種變化:
\{n\}: 重現n次 \{n,\}: 重現至少n次 \{n,m\}: 重現n至m次(n與m的值必須介於0至RE_DUP_MAX,該值可經過命令getconf RE_DUP_MAX得到)
擴展正則表達式:
匹配單個字符,如左方括號、連字符、右方括號或是反斜槓,應該用[\ [\-\] \\]
交替,即垂直的一條線,或稱爲管道字符(|)。他是ERE運算符中優先級最低的。
分組,((...))。和其餘字符結合起來使用時,分組仍是很是好用的。舉個例子:
^abcd|efgh$意思是「匹配字符串的起始處是否有abcd,或者結尾處是否有efgh」,和^(abcd|efgh)$不同,後者表示的是「找一個正式abcd或正式efgh的字符串」。
這裏要特別注意。
3、文本文件裏的替換
這一小節是重點,由於裏面涉及到一個很龐大的概念,即sed。sed最初的設計是用來以批處理的方式而不是交互的方式來編輯文件。然而,在Shell腳本里,sed主要用於一些簡單的文本替換。
sed基本用法:
1 一般在管道(pipeline)中間使用sed,以執行替換操做。作法是使用s命令,舉例以下:
sed 's/:.*//' /etc/passwd | sort -u //刪除第一個冒號以後的內容及排序列表並刪除重複部分
2 更新文件並備份源文件,舉例以下:
假如目前hello.xml中有這樣一段話,China,which is a most strong country of the world.
sed 's/China/&, the second biggest country of Asia/' < hello.xml.old > hello.xml
這樣就在原來的文檔中插入了一段話,同時將原有的hello.xml內容備份在文件hello.xml.old中
3 經過-e選項使用多個sed實體,例如:
sed -e 's/China/Russia/g' -e 's/strong/large/g' hello.xml > hello2.xml
不過,若是你有不少要編輯的項目,這種形式就很恐怖。因此,將編輯命令全放進一個腳本里,再使用sed搭配-f選項會更好:
$ cat hello.sed
s/China/Russia/g
s/strong/large/g
...
$ sed -f hello.sed hello.xml > hello2.xml
sed的運做原理:
命令行上的每一個文件名會依次打開與讀取。若是沒有文件,則使用標準輸入,用「-」表示。
sed逐行讀取每一個沒減,再將讀取到的行放到內存中的某個區域——稱爲模式空間。區域中的內容會隨着編輯命令應用在其上的操做不斷更新其中的內容。當全部操做完成後,sed會將模式空間的最後內容打印到標準輸出,再回到開始的位置,讀取下一行。
4、字段處理
其實數據也能夠視爲記錄與字段的結合,一條記錄是相關信息的單個集合,可視做數據庫中的data,而字段指的就是記錄的組成部分。能夠看作是數據庫中的field。
cut、join與awk
cut與join的用法這裏再也不作過多講述,只要記住一個是剪切字段,一個是拼接字段就好了,使用的時候藉助-man便可,很簡單。
這裏主要介紹下能夠和sed勢均力敵的一個重要指令——awk
awk用法:
awk主要用於取出字段並從新編排和一些簡易的文本處理。但因爲他自己鎖提供的功能完備,已經能夠算是一個很好用的程序語言了。
awk設計的重點在字段與記錄上:awk讀取輸入記錄,而後自動將各個記錄切分爲字段。或者,awk特別之處就是:也能夠設置它爲一個完整的ERE,這種狀況下,每個匹配在該ERE的文本都將視爲字段分隔字符。
awk的輸入、輸出分隔字符用法是分開的,這點與其餘工具程序不一樣。例如:
$ awk -F: '{ print $1, $5 }' /etc/passwd
-F選項會自動地設置FS變量。程序沒必要直接參照FS變量,也不用必須管理讀取的記錄並將它們分割爲字段:awk會自動完成這些事。
$ awk -F: -v 'OFS=**' '{ print $1, $5 }' /etc/passwd
root**root
...
haldaemon**HAL daemon
avahi**Avahi daemon
avahi-autoipd**avahi-autoipd
apache**Apache
ntp**
...
$ awk -F: '{ print "User", $1, "is really", $5 }' /etc/passwd
User root is really root
...
User daemon is really daemon
User adm is really adm
User lp is really lp
User sync is really sync
...
好了,第一節先到這裏。