Shell 查找與替換

1.文本查找 searching

傳統上,有3種程序可以用來查找整個文本文件。
1. grep 基本正則表達式
2. egrep 擴展正則表達式
3. fgrep 快速grep,匹配固定字符串而非正則表達式,它使用優化算法,能更有效的匹配固定字符串。
後來這三個都整合到了grep中。

1.簡單的grep

who | grep -F austen

使用-F選項查找固定字符串austen,事實上,只要匹配的模式裏未含有正則表達式的meta字符,則grep默認行爲模式就等同於使用了-F:

who | grep austen

2.正則表達

grep [options...] pattern-spec[files...]

用途 顯示匹配一個或多個模式的文本行。時常會作爲管道的第一步,以便對匹配的數據作進一步處理。
主要選項:
-E 使用擴展正則表達式進行匹配。grep -E 等於 egrep
-F 使用固定字符串進行匹配。grep -F 等於 fgrep
-e pat-list 通常,第一個非選項的參數會指定要匹配的模式,也可以提供多個模式,只要將他們放在引號裏並以換行符分隔他們。模式以減號開頭時,grep會混淆,將它視爲選項。這就是-e選項派上用場的時候,可以指定其參數爲模式——即使它以減號開頭。
-f pat-file 從pat-file文件提取模式做匹配
-i 模式匹配時忽略字母大小寫差異
-l 列出匹配模式的文件名稱,而不是打印匹配的行
-q 靜默的。如果模式匹配成功,則grep會成功的離開,而不將匹配的行寫入標準輸出;否則即是不成功。
-s 不顯示錯誤信息。通常與-q 並用。
-v 顯示不匹配模式的行。
行爲模式 讀取命令行上指明的每個文件,發現匹配查找模式的行時,將它顯示出來。當指明多個文件時,grep會在每一行前面加上文件名與一個冒號。默認使用BRE(basic regular expression,基本的正則表達式)。
可以使用多個 -e -f選項,建立要查找的模式列表。

字符 BRE/ERE 模式含義
\ 兩者都可 通常用來關閉後續字符的特殊意義,有時則是打開後續字符的特殊意義。如\(...\)與\{..\}
. 兩者都可 匹配任何單個的字符,但NUl除外
* 兩者都可 匹配在他之前的任何數目(或沒有)的單個字符。如.*匹配任一字符的任意長度
^ 兩者都可 匹配緊接着的正則表達式,在行或字符串的起始處
$ 兩者都可 匹配前面的正則表達式,在字符串或行結尾處
[…] 兩個都可 方括號表達式,匹配方括號內的任一字符,^在方括號裏的第一個字符則說明匹配不在方括號內的任何字符[^A-Z]:匹配不是大寫的A-Z之間的字符
\{n,m\} BRE 區間表達式,匹配在它前面的單個字符重現的次數區間。\{n\}指的是重現n次,\{n,\}爲至少重現n次,\{n,m\}爲重現n-m次
\( \) BRE 將(與)之間的模式存儲在特殊的保留空間hoding space中,最多可存儲9個獨立的子模式,可通過轉義序列\1到\9被重複用在相同模式裏,例如(ab).*\1,指的是匹配於ab組合的兩次重現,中間可能存在任何數目的字符。
\n BRE 重複在(和)括號內第n個子模式至此點的模式。n爲1-9的數字,1爲由左開始。
{n,m} ERE 和{n,m}一樣
+ ERE 匹配前面正則表達式的一個或多個實例
ERE 匹配前面正則表達式的0個或一個實例
| ERE 匹配於|符號前或後的正則表達式
() ERE 匹配括號括起來的正則表達式羣

範例:

表達式 匹配
tolstoy 位於一行上任何位置的7個字母:tolstoy
^tolstoy 7個字母tolstoy,出現在行的開頭
tolstoy$ 7個字母tolstoy,出現在行的結尾
[Tt]olstoy 在一行上的任意位居中,含有Tolstoy或tolstoy
tol.toy 含有tol加上任何一個字符,再接着toy這3個字母
tol.*toy 在一行上的任意位置居中,含有tol這3個字母,加上任意的0或多個字符,再繼續toy這3個字母,如toltoy,tolstoy,tolWHOtoy等

POSIX字符集:

類別 匹配字符
[:alnum:] 數字字符
[:alpha:] 字母字符
[:blank:] 空格space與定位tab字符
[:cntrl:] 控制字符
[:digit:] 數字字符
[:graph:] 非空格字符
[:lower:] 小寫字母字符
[:print:] 可顯示的字符
[:punct:] 標點符號字符
[:space:] 空白字符
[:upper:] 大寫字母字符
[:xdigit:] 十六進制數字

在方括號表達式中,所有其他的meta字符都會失去其特殊含義。所以[*\.]匹配於字面上的星號,反斜槓以及句點。要讓]進入該集合,可以將它放在列表的最前面:[]*\.],要讓減號字符進入該集合,也要放到最前面[-*\.],]和-一起選擇的話,]放到第一個,減號放到最後一個:[]*\.-]

後向引用:
\(ab\)\(cd\)[def]*\2\1:adcdcdab,abcdeeecdab, abcdddeeffcdab,…
(why).*\1:一行裏有兩個why

在文本文件裏進行替換

sed

一般來說,執行文本替換的正確程序應該是 sed ——流編輯器(Stream Editor),sed的設計就是用來以批處理的方式而不是交互的方式來編輯文件。當你知道要做好幾個變更,比較簡單的方式是將這些變更部分寫到一個編輯中的腳本里,再將此腳本應用到所有必須修改的文件。

sed 's/:.*//' /etc/passwd | sort -u:刪除第一個冒號之後的所有東西,排序列表並刪除重複部分。

cut

語法
cut -c list[file ...]
cut -f list[-d lelim][file...]
用途
從輸入文件中選擇一或多個字段或者一組字符,配合管道(pipeline),可再做進一步處理。
主要選項:
-c list
    以字符爲主,執行cut操作。list爲字符編號或一段範圍的列表(以逗點隔開),如1,3,5-12,42
-d delim 通過-f選項,使用delim作爲定界符,默認爲tab
-f list 以字段爲主,坐剪下的操作。list爲字段編號或一段範圍內的列表,以逗號隔開。
$ ls -l | cut -c 1-10

使用join連接字段

語法 join [options ...] file1 file2
用途 以共同一個鍵值,將已存儲文件內的記錄加以結合。
選項:
-1 field1  
-2 field2
-1 field1 是從file1中取出字段field1,-2 field2是從file2取出field2.字段編號自1開始,而非0.
-o file.field
    輸出file文件中的field字段。一般的字段則不打印。除非使用多個-o選項,即可顯示多個輸出字段。
-t separator:使用separator作爲輸入字段分隔字符,而非使用空白。此字符也爲輸出的字段分隔字符。
cat sales
#業務員數據
#業務員 量
joe 100
jane 200
herman 150
chris 300

cat quotas
#配額
#業務員  配額
joe   50
jane  75
herman 80
chris  95

# 爲了讓join得到正確結果,輸入文件必須先完成排序。
merge-sales.sh
#!/bin/sh
# 刪除註釋並排序數據文件
sed '/^#/d' quotas | sort > quotas.sorted
sed '/^#/d' sales | sort > sales.sorted
#以第一個鍵值作結合,將結果產生至標準輸出
join quotas.sorted sales.sorted

awk

awk 'program' [file ...]
awk程序基本架構爲:
pattern {action}
...|awk '{print some-stuff}'|...
例如:
awk '{print $1}' 打印第一個字段(未指定pattern)
awk '{print $2,$5}' 打印第2與第5個字段(未指定pattern)
awk '{print $1, $NF}'打印第一個與最後一個字段,未指定pattern
awk 'NF > 0  {print $0}'打印非空行,指定pattern與action,$0表示整條記錄
awk 'NF>0' 同上
awk -F: '{print $1, $5}' /etc/passwd #處理/etc/passwd,以:作爲分隔符

awk -F: '{print "User", $1, "is really", $5}' /etc/passwd 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章