詳見;http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt103
文件操作和過濾
絕大多數命令行工作是針對文件的。我們會在本節中討論如何觀察及過濾文件內容,使用一條命令從文件中提取所需信息,以及對文件的內容進行排序。
cat、tail、head、tee:文件打印命令
這些命令的語法基本上相同的:命令名 [選項] [文件],而且您可以在管道中使用這些命令。這些命令的功能都是根據特定的條件選擇文件內容進行打印。
cat 工具會將文件的全部內容打印到標准輸出。
這是最常用的命令之一。例如,您可以使用:
# cat /var/log/mail/info
將郵件程序守護程序日志的內容打印到標准輸出[14]。
cat 命令有一個非常有用的選項(-n),該選項將允許您打印行號。
某些文件,如守護程序日志文件(如果相應的守護程序運行了的話)可能非常大[15],在屏幕上打印全部內容可能沒什么必要。
您經常只是需要看看一個文件的某幾行。
您可以使用 tail 命令完成這一功能。默認情況下,下面的命令將會打印 /var/log/mail/info 文件的最后十行:
# tail /var/log/mail/info
您可以使用 -n 選項顯示文件的最后 N 行。例如,要顯示最后兩行,您應該執行:
# tail -n2 /var/log/mail/info
而 head 命令與 tail 十分相似,只是打印文件的頭幾行。默認情況下,下面的命令將會打印 /var/log/mail/info 文件的頭十行:
# head /var/log/mail/info
和 tail 一樣,您也可以使用 -n 選項指定要打印的行數。例如,要打印前兩行,您應該執行:
# head -n2 /var/log/mail/info
您還可以組合使用這幾條命令。
例如,如果您想要只顯示第九行和第十行,您可以先使用 head 命令選擇文件的前十行,然后再將結果通過管道送到 tail 命令。
# head /var/log/mail/info | tail -n2
豎線后面的部分將選擇最后兩行,然后將其打印到屏幕。同樣地,您也可以選擇只打印文件的倒數第 20 行:
# tail -n20 /var/log/mail/info |head -n1
在本例中,我們讓 tail 選擇了文件的最后 20 行,然后將結果通過管道傳送給 head。然后 head 命令將會從得到的數據中取出第一行打印到屏幕上。
現在我們假定您想要將上例中的結果在屏幕上顯示的同時還保存到文件 results.txt。
tee 工具可以幫到我們。其語法是:
tee [選項] [文件]
現在,我們可以將上一命令做如下更改:
# tail -n20 /var/log/mail/info |head -n1|tee results.txt
我們再來舉一個例子。我們想要選擇最后 20 行,將其保存到 results.txt,但是只在屏幕上顯示這 20 行中的第一行。那么,我們應該輸入:
# tail -n20 /var/log/mail/info |tee results.txt |head -n1
tee 命令有一個非常有用的選項(-a),它允許您將數據追加到已有文件。
讓我們再回過頭來看看 tail 命令。像日志這樣的文件應該是在不斷變化的,因為與其相關的守護程序每時每刻都在記錄着它所執行的動作和發生的事件。所以,如果您想要交互地觀看日志文件,您可以使用 -f 選項:
# tail -f /var/log/mail/info
在本例中,/var/log/mail/info 文件的所有更改都會立即打印到屏幕上。當您想要知道您系統的工作原理時,使用帶 -f 選項的 tail 命令將非常有用。例如,通過查看 /var/log/messages 日志文件,您可以時刻跟蹤系統信息和各種守護程序。
在下一節中,我們將會看到如何將 grep 用作過濾器,以便從來自其它服務的信息中拆出 Postfix 信息。
grep: 定位文件中的字符串
不管是命令的名字還是縮寫(“General Regular Expression Parser”)都顯得非常古怪,但該命令的作用和用法卻很簡單:grep 將在一個或多個文件中查找給定的模式。其語法為:
grep [選項] <模式> [一個或多個文件]
如果列出了多個文件,將會在每一行結果的開頭附加相應的文件名。使用 -h 選項可以不顯示這些文件名;使用 -l 選項可以只列出文件名。模式是一個正則表達式,盡管在大多數情況下只是一個簡單的單詞。下面列出了最常用的幾個選項:
-i:進行不區分大小寫的搜索;
-v:反轉搜索。顯示不與模式匹配的行;
-n:顯示找到行的行號;
-w:讓 grep 在進行模式匹配時匹配整個單詞。
讓我們回到對郵件守護程序日志文件的分析中。我們想要在 /var/log/mail/info 中找到包含“postfix”模式的所有行。我們就需要輸出這個命令:
# grep postfix /var/log/mail/info
grep 命令可用於管道。這樣,下面的命令與上面的例子所得到的結果相同:
# cat /var/log/mail/info | grep postfix
如果我們想要找到不與“postfix”模式匹配的所有行,我們就應該使用 -v 選項:
# grep -v postfix /var/log/mail/info
現在,我們假定想要查找關於成功發出的郵件的全部信息。這樣,我們需要找到郵件守護程序(包含“postfix”模式)在日志文件中添加的行,而且這些行還必須包含成功發送的信息(“status=sent”):
# grep postfix /var/log/mail/info |grep status=sent
我們在本例中使用了兩次 grep。這種方法雖然可以達到我們的目的,但顯得有點麻煩。我們可以使用 fgrep 工具達到相同的效果。首先,我們需要創建一個包含需要匹配的模式的文件。這樣的文件可以用這種方式來創建(我們使用 patterns.txt 來作為文件名):
# echo -e 'status=sent postfix' >./patterns.txt
然后,我們將會用 patterns.txt 文件中的模式列表作為參數調用 fgrep 工具,而不是“兩次調用”grep:
# fgrep -f ./patterns.txt /var/log/mail/info
文件 ./patterns.txt 可以包含您喜歡的任意多個模式。每個模式都必須獨占一行。
例如,要選擇已經成功發送給 的郵件的有關信息,只需將此電子郵件地址添加到 ./patterns.txt 文件,試試這條命令:
# echo 'peter@mandrakesoft.com' >>./patterns.txt
顯然,您可以將 grep 與 tail 或者 head 組合起來使用。如果我們想要查找上上次發送給 的郵件,只需輸入:
# fgrep -f ./patterns.txt /var/log/mail/info | tail -n2 | head -n1
在這里,我們應用了上面講述的過濾器,並將其放入 tail 和 head 命令的管道。這將會從數據中取出倒數第二行。
wc:統計文件中的元素
wc 命令(Word Count)用於統計文件中的字符串的數量。它還可用於統計字節數、字符數以及最長行的長度。其語法為:
wc [選項] [文件]
下面的選項比較有用:
-l:打印換行符數;
-w:打印單詞數;
-m:打印總計字符數;
-c:打印字節數;
-L:打印所獲取文本中最長行的長度。
wc 命令默認情況下會打印換行符數、單詞數和字符數。下面是一些例子:
如果我們想要查找系統中的用戶數,我們就可以輸入:
$wc -l /etc/passwd
如果我們想要知道系統中的 CPU 數,我們可以輸入:
$grep "model name" /proc/cpuinfo |wc -l
在上一節中,我們通過 ./patterns.txt 文件獲取了成功發送到指定電子郵件地址的郵件列表。如果我們想要知道一共有多少封郵件,那么可以將過濾結果重定向到 wc 命令的管道:
# fgrep -f ./patterns.txt /var/log/mail/info | wc -l
sort:排序文件內容
下面列出了這一強大工具的語法[16]:
sort [選項] [文件]
現在我們來考慮一下對 /etc/passwd 文件進行排序。正如您看到的,這個文件並未經過排序:
$ cat /etc/passwd
如果我們想要按照 login 域進行排序,則應輸入:
$ sort /etc/passwd
默認情況下,sort 命令會按照第一個域(本例中就是 login)對數據進行升序排序。如果我們想要以降序方式排序,可以使用選項 -r:
$ sort -r /etc/passwd
每個用戶在 /etc/passwd 文件中都有他自己的 UID。現在我們來試試按照 UID 域進行升序排序:
$ sort /etc/passwd -t":" -k3 -n
我們在這里用到了下列 sort 選項:
-t":":通知 sort 域之間通過 ":" 符號分隔;
-k3:意味着要根據第三列進行排序;
-n:表明排序是按照數字順序,而非字母順序。
如果要想按照降序排序,就是:
$ sort /etc/passwd -t":" -k3 -n -r
請注意,sort 還有兩個比較重要的選項:
-u:執行嚴格定序:重復的排序關鍵字將被丟棄;
-f:忽略大小寫。
最后,如果我們想要找到 UID 最高的用戶,可以使用這條命令:
$ sort /etc/passwd -t":" -k3 -n |tail -n1
我們先是對 /etc/passwd 文件按 UID 進行了升序排序,然后將結果通過管道傳送給 tail 命令,它會輸出排序列表的最后一行。