天天看點

來聊一聊不low的Linux指令——find、grep、awk、sed

前幾天面試,被一位面試官嫌棄了“你的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>

來聊一聊不low的Linux指令——find、grep、awk、sed

模糊查找:<code>find ~ -name "spur*"</code>

來聊一聊不low的Linux指令——find、grep、awk、sed

模糊查找可以找到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>

來聊一聊不low的Linux指令——find、grep、awk、sed

計算比對的行的數目:<code>grep -c for spur.txt</code>

來聊一聊不low的Linux指令——find、grep、awk、sed

管道操作符“|”可将指令連接配接起來,前一個指令的輸出作為後一個指令的輸入。注意:隻有前一個指令正确輸出的時候,才會處理後一個指令。例如:<code>find ~ | grep for</code>

來聊一聊不low的Linux指令——find、grep、awk、sed
管道和重定向的差別:管道是一個連接配接一個進行計算;重定向是将一個檔案的内容定向到另一個檔案;這二者經常結合使用。

比對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的檔案,檔案内容如下:

來聊一聊不low的Linux指令——find、grep、awk、sed

使用awk指令檢視全部檔案内容:<code>awk '{print}' spur.txt</code>

print是awk的内置函數,用于列印出變量的值。

來聊一聊不low的Linux指令——find、grep、awk、sed

列印某一列或者某幾列:$1為第1列,$2為第2列,...($0表示全部)

以列印第1列和第4列為例:<code>awk '{print $1,$4}' spur.txt</code>

來聊一聊不low的Linux指令——find、grep、awk、sed

分隔符的使用。

awk認為“,”為系統預設分隔符,“ ”為直接連接配接起來。

來聊一聊不low的Linux指令——find、grep、awk、sed

例如第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>

來聊一聊不low的Linux指令——find、grep、awk、sed

内置變量NR和NF的使用。

Awk定義一行為一個record,一列為一個field。NR為行數(number of record),NF為列數(number of field)。

例如查找列印最後一列為2794的記錄并列印:<code>awk '$NF==2794{print $0}' spur.txt</code>

來聊一聊不low的Linux指令——find、grep、awk、sed

BEGIN語句塊和END語句塊。

BEGIN用于awk 開始處理輸入檔案中的文本之前執行初始化代碼。

END用于執行最終計算或列印應該出現在輸出流結尾的摘要資訊。

繼續以分隔符舉例,我們可以使用BEGIN語句塊來定義全局變量,FS為輸入分隔符,OFS為輸出分隔符。

提示:如果awk指令後面不加檔案名,awk則認為下一行輸入的内容為需要處理的内容。

設定“,”為輸入分隔符,“\t”為輸出分隔符:

來聊一聊不low的Linux指令——find、grep、awk、sed

正規表達式(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>

來聊一聊不low的Linux指令——find、grep、awk、sed

比對第3列以“te”結尾,列印所有的列:<code>awk '$3 ~ /(te)$/{print $0}' spur.txt</code>

來聊一聊不low的Linux指令——find、grep、awk、sed

注意:“~”表示模式開始。“//” 中是模式。

這是一道我面試某視訊娛樂公司的面試題,像這種難度的小問題還希望大家多重視。

更多的操作可以參考: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指令的基本使用方法,希望對大家有幫助。

由于部落客也是在攀登的路上,文中可能存在不當之處,歡迎各位多指教! 如果文章對您有用,那麼請點個”推薦“,以資鼓勵!

繼續閱讀