前幾天面試,被一位面試官嫌棄了“你的Linux指令有點low”。說心裡話,還是挺感激的,因為很少有面試官會指出我的履歷上出現的問題。是以呢,今天就來聊一聊不low的Linux指令——搜尋檔案的find指令、搜尋檔案内容的grep指令、對檔案内容進行統計的awk指令、批量替換檔案内容的sed指令。
前幾天面試,被一位面試官嫌棄了“你的Linux指令有點low”。被嫌棄也挺正常的,因為我的履歷寫的我自己都有點看不下去:了解Linux常用指令,如<code>ls</code>,<code>tail -f</code>等指令,基本滿足日常的開發。面試官人很好,整個面試進行地也很愉快。說心裡話,還是挺感激的,因為很少有面試官會指出我的履歷上出現的問題。是以呢,今天就來聊一聊不low的Linux指令——搜尋檔案的find指令、搜尋檔案内容的grep指令、對檔案内容進行統計的awk指令、批量替換檔案内容的sed指令。
find指令是一個用于搜尋檔案的指令。find指令的基本文法:<code>find path [option] params</code>
path為搜尋檔案的路徑,可以是相對路徑,也可以是絕對路徑,還可以指定多個路徑,如:<code>find /var /home</code>。
主要選項(option)如下:
選項
含義
-depth
在檢視目錄本身之前先搜尋目錄的内容
-follow
跟随符号連結
-maxdepths N
最多搜尋N層目錄
-mount
不搜尋其他檔案系統中的目錄
主要參數(param)如下:
參數
-atime N
檔案在N天之前被最後通路過
-mtime N
檔案在N天之前被最後修改過
-name pattern
檔案名需要比對pattern
-newer otherfile
檔案比其他檔案要新
-type c
檔案類型為c,最常見的是d(目錄)和f(普通檔案)
-user username
檔案的擁有者是username
-size +1M
檔案大小。例子為查找檔案大小大于1M的。
-perm 644
檔案權限。例子為查找檔案權限為644的。
精确查找檔案:<code>find ~ -name "spur.java"</code>

模糊查找:<code>find ~ -name "spur*"</code>
模糊查找可以找到spur開頭的檔案和目錄,那如果要單獨查找目錄或者單獨查找檔案怎麼辦呢?
其實有個<code>-type</code>可以用來篩選目錄和檔案,查找檔案在上面的指令後面添加<code>-type f</code>,查找目錄加<code>-type d</code>。
忽略檔案名大小寫進行查找檔案:<code>find ~ iname "spurt*"</code>
查找檔案并恢複檔案權限:<code>find -type f -exec chmod -R 644 {} \;</code>
删除30天之前的日志檔案:<code>find -type f -name "*.log" -mtime +30 -exec rm -rf {} \;</code>
grep (縮寫來自Globally search a Regular Expression and Print)是一種強大的文本搜尋工具,它能使用特定模式比對(包括正規表達式)搜尋文本,并預設輸出比對行,基本文法為<code>grep [options] pattern [file]</code>
如果沒有提供檔案名,則grep指令将會搜尋标準輸入。
主要選項(option)如下表:
-c
輸出比對行的數目
-h
取消每個輸出行的普通字首
-i
忽略大小寫
-l
查找多個檔案,隻列出包含比對行的檔案名
-v
反向查找
-n
順便輸出行号
在檔案中搜尋字元串,然後輸出比對的行。例如比對檔案spur.txt中的字元串for,并輸出整行,要求帶行号:<code>grep -n for spur.txt</code>
計算比對的行的數目:<code>grep -c for spur.txt</code>
管道操作符“|”可将指令連接配接起來,前一個指令的輸出作為後一個指令的輸入。注意:隻有前一個指令正确輸出的時候,才會處理後一個指令。例如:<code>find ~ | grep for</code>
管道和重定向的差別:管道是一個連接配接一個進行計算;重定向是将一個檔案的内容定向到另一個檔案;這二者經常結合使用。
比對ip位址:<code>egrep --color "([0-9]{1,3}\.){3}[0-9]{1,3}$" test.txt</code>
AWK是Unix系統下一個非常強大的文本處理工具。AWK其名稱得自于它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。實際上 AWK 本身也可以作為一門計算機腳本語言。它允許建立簡短的程式,這些程式可以讀取輸入檔案、為資料排序、處理資料、對輸入執行計算以及生成報表等其他的功能。
awk知識要點
文法:<code>awk [options] 'cmd' file</code>
一次讀取一行文本,按輸入分隔符進行切片,切成多個組成部分(一行為一個record,一列為一個field)
将切片直接儲存在内建的變量中,$1,$2...($0表示行的全部)
支援對單個切片的判斷,支援循環判斷,預設分隔符為空格
這裡有個spur.txt的檔案,檔案内容如下:
使用awk指令檢視全部檔案内容:<code>awk '{print}' spur.txt</code>
print是awk的内置函數,用于列印出變量的值。
列印某一列或者某幾列:$1為第1列,$2為第2列,...($0表示全部)
以列印第1列和第4列為例:<code>awk '{print $1,$4}' spur.txt</code>
分隔符的使用。
awk認為“,”為系統預設分隔符,“ ”為直接連接配接起來。
例如第2個例子中<code>awk '{print $1,$4}' spur.txt</code>,使用的是預設分隔符,結果兩列之間有空格隔開的。
本例子使用<code>awk '{print $1 $4}' spur.txt</code>,使用的是直接相連,結果兩列之間沒有空格隔開。
當然,也可以自定義分隔符。如果希望用“-”分割,可以這麼寫:<code>awk '{print $1 "-" $4}' spur.txt</code>
内置變量NR和NF的使用。
Awk定義一行為一個record,一列為一個field。NR為行數(number of record),NF為列數(number of field)。
例如查找列印最後一列為2794的記錄并列印:<code>awk '$NF==2794{print $0}' spur.txt</code>
BEGIN語句塊和END語句塊。
BEGIN用于awk 開始處理輸入檔案中的文本之前執行初始化代碼。
END用于執行最終計算或列印應該出現在輸出流結尾的摘要資訊。
繼續以分隔符舉例,我們可以使用BEGIN語句塊來定義全局變量,FS為輸入分隔符,OFS為輸出分隔符。
提示:如果awk指令後面不加檔案名,awk則認為下一行輸入的内容為需要處理的内容。
設定“,”為輸入分隔符,“\t”為輸出分隔符:
正規表達式(Regular Expression)的使用。
正規表達式估計大家都比較了解,就不多唠叨了,下面列出幾個常用的:
字元
描述
.
比對任意一個字元
^
比對開頭。/^abc/比對以abc開頭字元串
$
比對結尾。/abc$/比對以abc結尾的字元串
[abc]
字元集合。比對所包含的任意一個字元。
[^a-z]
^放在方括号裡面表示非。<code>[^a-z]</code>比對不是a-z的字元串
*
比對前面的子表達式零次或多次。
+
比對前面的子表達式一次或多次。
?
比對前面的子表達式零次或一次。
{n}
比對n次。<code>/ab{3}c/</code>比對b出現3次。
{n,m}
比對n-m次。<code>ab{3,10}c</code>比對b可以出現3次至10次。
{n,}
至少比對n次。<code>/ab{3,}c/</code>比對b出現3次及3次以上。
()
()看成一個整體。<code>/(ab)+c/</code>:ab作為一個整體,至少出現一次。
例如需要比對出馬刺隊所有的後衛球員,也就是正則比對spur.txt中包含<code>guard</code>的記錄:<code>awk '/guard/{print $0}' spur.txt</code>
比對第3列以“te”結尾,列印所有的列:<code>awk '$3 ~ /(te)$/{print $0}' spur.txt</code>
注意:“~”表示模式開始。“//” 中是模式。
這是一道我面試某視訊娛樂公司的面試題,像這種難度的小問題還希望大家多重視。
更多的操作可以參考:Awk官方文檔
Sed的全名為Stream Editor,流編輯器,适合用于對文本的行内容進行處理。基本文法為:<code>sed [option] 'sed command' filename</code>
常用的選項:
使用安靜模式
-e
直接在指令列模式上進行 sed 的動作編輯
-f
直接将 sed 的動作寫在一個檔案内, -f filename 則可以執行 filename 内的sed 動作
-r
在腳本中使用擴充正規表達式
直接修改讀取的檔案内容,而不是将修改結果輸出到終端上
常用的指令:
指令
a
新增行
c
取代行
d
删除行,d 後面通常不加任何字元
i
插入行
p
列印
s
替代
删除指定的行(删除1-3行為例):<code>sed '1,3d' replace.txt</code>
新增一行:<code>sed '1a hello world' replace.txt</code>
替換某行:<code>sed '1c hello world' replace.txt</code>
把“Str”開頭的行替換為“String”,僅輸出到終端顯示:<code>sed 's/^Str/String/' replace.txt</code>
字元串替換,把<code>replace.txt</code>中全部的“Jack”替換為“me”,要求在文檔中修改:<code>sed -i 's/Jack/me/g' replace.txt</code>
替換末尾的“.”為“;”:<code>sed -i 's/\.$/\;/' replace.java</code>
本文介紹了find指令、grep指令、awk指令、sed指令的基本使用方法,希望對大家有幫助。
由于部落客也是在攀登的路上,文中可能存在不當之處,歡迎各位多指教! 如果文章對您有用,那麼請點個”推薦“,以資鼓勵!