系統管理員工作過程中,總會遇到小的、瑣碎的、各種各樣的文本處理問題,如果對文本處理不熟,每一次都要查很多的資料去解決這樣的小問題,那么系統管理員的工作效率從何而來。因此如何快速寫出簡短有效的針對特定問題的文本處理程序,是系統管理員的基本功之一,也是能夠大大提高系統管理員的工作效率的技能之一。
說是文本處理,其實是對文本流的處理,與此相對的還有二進制流。文本處理就是對輸入文本流進行相應的操作、轉換然后寫入到輸出文本流中。我們知道Linux下默認給每個進程打開三個流,分別是標准輸入、標准輸出以及標准錯誤流,更底層一點的,這三個流分別對應於文件描述符0、1和2。對於特定的進程,還可以打開自己的流,進行輸入輸出。文本處理操作就發生在文本從一個流到另一流之間的過程中。
Linux與文本處理相關的命令主要有:cat、head、tail、wc、column、sort、split、join、uniq、tr、cut、diff、patch等,當然還有很多其它的文本處理相關的指令,但是掌握這幾個指令,簡單的文本處理就是手到擒來的事。
1、cat - 貼出一個文件的內容,從文件中獲取輸入,並將該文件內容輸出到標准輸出
指令格式:
$ cat [OPTION]... [FILE]...
cat指令功能雖然簡單,但是配合重定向,它就可以將一個文件內容送給任何可以從標准輸入獲取數據的工具來進行處理。
cat指令本身有一些選項(不太常用),通過這些選項可以在貼出文本流之前就對文本進行簡單的處理。
常用選項:
-b 對非空行編號,並顯示其行號
-n 對所有行編號,並顯示其行號
-E 在每一行后顯示$
-T 將制表符顯示為^I
實例:
將一個文件的內容送給column指令:
$ cat /etc/passwd | column -s: -t
這條指令的作用將文件/etc/passwd的內容進行按列對齊進行顯示。column指令在后面會有詳細說明。對於可以直接從從文件中獲取數據的指令,這樣做顯得多此一舉,但是對於一些要求從標准輸入獲取數據的指令來說,通過cat和管道無疑是非常不錯的一種方式。
2、head - 用於顯示一個文件的前幾行
指令格式:
$ head [OPTION]... [FILE]...
head指令用於從文件頭開始顯示幾行,它比cat多出了可以按行選擇文件中需要輸出的部分。同cat一樣,它默認從文件中獲取內容,輸出到標准輸出。當需要對某個文件的頭幾行、幾十行等內容進行文本處理時,head指令就可以幫上忙。
相比於cat,head指令提供的功能可能顯得更有用。
常用選項:
-c m 輸出文件內容的前m個字節,這里m是一個數字
-n m 輸出文件內容的前m行的文本,這里m是一個數字
-n 輸出文件內容的前n行,這里n輸一個數字
實例:
若只需要/etc/passwd文件前三行內容,並將它送給column指令處理,可以像向下面這樣處理:
$ head -3 /etc/passwd | column -s: -t
3、tail - 用於顯示一個文件的后幾行
指令格式:
$ tail [OPTION]... [FILE]...
tail指令用於從文件結尾開始顯示幾行,與head指令的作用剛好相反。同樣,tail指令從文件中獲取數據,輸出到標准輸出。
常用選項:
-c m 輸出后m字節,同樣,這里m是一個數字
-n m 輸出后m行的文本,這里m是一個數字
-n 輸出后n行,這里n輸一個數字
實例:
比如需要/etc/passwd文件的第3到10行,可以像下面這樣做:
$ head -10 /etc/passwd | tail -7
4、wc - 用於統計一個文本流有多少的字符、單詞或單位行
指令格式:
$ wc [OPTION]... [FILE]... $ wc [OPTION]... --files0-from=F
根據使用的選項的不同,wc指令可以對文件進行按字符、單詞和行進行統計。
常用選項:
-c 打印文件的字節數
-m 打印文件的字符數
-w 打印文件的單詞個數
-l 打印文件的行數
-L 打印文件的最長一行的長度
--files0-from=F 從文件F中獲取文件名
不帶任何選項的wc指令將分別打印文件的行數、單詞數、以及行數。
實例:
需要注意的是對於中文文本,需使用選項m來獲取文件的中文字符個數。比如獲取/etc/passwd文件的行數:
$ wc -l /etc/passwd
5、tr - 用於把一組字符轉化為另一組字符,或者刪除特定字符
指令格式:
$ tr [OPTION]... SET1 [SET2]
tr指令從標准輸入獲取文本流數據,因此常備用在管道的后端進行字符過濾處理,用來轉換或刪除文本流的中的指定的字符(集)。
常用選項:
-c 取后邊SET1字符集合的補集
-d 刪除出文本中出現的包含在SET1字符集中的字符
-s 壓縮字符,若文本流中某個字符出現在SET1中且連續多次,則壓縮成一個字符,即把多個重復字符變成一個字符
-t 先將文本中出現的包含在SET1中的字符序列截斷到字符集SET2的長度,然后進行一一對應的轉換
所謂字符集,就是一組字符的集合,對於tr指令而言,更精確地說字符集就是一個字符串。字符集的表示方式如下:
CHAR1-CHAR2 從字符CHAR1到CHAR2的所有字符
[CHAR*] 出現在SET2中,表示重復CHAR字符,直到SET2字符集的長度與SET1長度相同
[CHAR*REPEAT] 重復CHAR字符REPEAT次,這里REPEAT可以十進制或者八進制(以0開始)數字
[:alnum:] 表示所有的字母和數字組成的字符集
[:alpha:] 表示所有字母組成的字符集
[:lower:] 表示所有小寫字母組成的字符集
[:upper:] 表示所有大寫字母組成的字符集
[:print:] 表示所有可打印的字符組成的字符集,包括空白字符
[:blank:] 表示所有水平空白字符集合
[:cntrl:] 表示所有的控制字符
[:space:] 表示所有的空白字符(包括水平空白字符和垂直空白字符)
這里CHAR表示一個字符,可以是一般可表示的字符,如大小寫字母或者數字,也可以是轉義字符。轉義字符的定義類似於C語言中的轉義字符,常用的幾個如下:
\n 換行符
\r 回車符
\t 水平制表符
實例:
將一個文件中所有大寫字母裝換成小寫字母:
$ cat test.txt | tr 'A-Z' 'a-z'
$ tr 'A-Z' 'a-z' < test.txt # 等價於上面的形式
使用tr指令需要注意,它並不能直接從文件獲取數據,它從標准輸入獲取數據,因此放在通常管道右邊來過濾字符。
6、sort - 用於對文件進行排序
指令格式:
$ sort [OPTION]... [FILE]... $ sort [OPTION]... --files0-from=F
sort指令按照行對文件進行排序,默認排序方式是ascii字符集的順序。
常用選項:
-b 忽略前置的空白字符
-d 只考慮字母、數字字符
-M 按月份英文名(三字母縮寫)
-n 用於按數字排序,而非按數字字符的ascii碼排序
-r 反向排序
--files0-from=F 從文件F中獲取文件名
實例:
使用sort對文件的內容進行排序時一定要注意是以什么標准進行排序的,因此上面提到的選項是非常重要的。如下:
$ sort -r test1.txt test2.txt
這條指令對文件test1.txt和文件test2.txt進行合並,然后反向排序並輸出。
7、uniq - 打印重復單詞中的一個,加上特定選項可以計算重復單詞出現的次數
uniq [-c] file
選項含義如下:
c 計算重復單詞出現的次數,輸出兩列,一列是單詞出現次數,一列是單詞
需要注意的uniq只能用於已經排序的文本才能起到計算或剔除重復的文本行的效果。
一個組合上面的命令的有用的命令如下:
awk '{print $1}' ~/.bash_history | sort | uniq -c | sort -nr | head -10
這條指令的作用就是打印用戶最常用的10條命令。
8、column
9、split
10、join