Linux系統中的管道命令、grep命令、sed命令和awk命令

谢友海發表於2024-08-12

本章將和大家分享Linux系統中的管道命令、grep命令、sed命令和awk命令。廢話不多說,下面我們直接進入主題。

一、管道命令

Linux 中的管道命令(pipe)是一種非常強大的特性,它允許你將一個命令的輸出作為另一個命令的輸入。管道命令極大地增強了命令列的靈活性和功能,使得複雜的資料處理任務變得簡單。

1、基本語法

command1 | command2

command1 的輸出會被傳遞給 command2 作為其輸入。

可以鏈式使用多個管道命令,例如 command1 | command2 | command3。

2、示例

1)檢視系統程序並按記憶體使用量排序

ps aux --sort=-%mem | less

這裡,ps aux --sort=-%mem 命令列出所有程序並按記憶體使用率降序排序,然後透過管道傳遞給 less 命令,使得你可以逐頁檢視輸出。

2)查詢包含特定文字的檔案,並計算行數

grep '特定文字' 檔名 | wc -l

這裡,grep '特定文字' 檔名 命令查詢檔案中包含“特定文字”的行,然後將這些行傳遞給 wc -l 命令來計算行數。

3)檢視當前目錄的檔案和目錄,然後僅顯示目錄

ls -l | grep '^d'

ls -l 命令以長格式列出當前目錄的內容,然後透過管道傳遞給 grep '^d' 命令,後者僅匹配以 d(表示目錄)開頭的行。

4)使用多個管道進行復雜的資料處理

假設你有一個日誌檔案,你想要找出所有錯誤訊息(假設以 "ERROR" 開頭),並計算這些訊息的數量,同時忽略大小寫:

grep -i 'error' 日誌檔案.log | wc -l

這裡,grep -i 'error' 日誌檔案.log 命令使用 -i 選項忽略大小寫地查詢包含 "error" 的行,然後透過管道傳遞給 wc -l 命令來計數。

3、注意事項

  • 管道命令中的每個命令都在其子 shell 中執行,因此它們之間的變數不是共享的。
  • 管道命令中每個命令的輸入和輸出都是透過標準輸入(stdin)和標準輸出(stdout)進行的,除非特別重定向了輸入或輸出。
  • 管道命令中的錯誤輸出(stderr)預設不會傳遞給下一個命令,除非使用重定向或特殊的命令(如 2>&1)來合併標準輸出和錯誤輸出。

二、grep命令

主要作用是檔案過濾分割與合併,grep(global search regular expression(RE) and print out the line,全面搜尋正規表示式並把行列印出來)是一種強大的文字搜尋工具,它能使用正規表示式搜尋文字,並把匹配的行列印出來。

1、基本語法

grep [選項]... 模式 [檔案]...
  • 選項:可以調整 grep 的行為,如忽略大小寫、顯示匹配行的行號等。
  • 模式:指定要搜尋的文字模式,可以是簡單的字串或複雜的正規表示式。
  • 檔案:指定要搜尋的檔名。如果沒有指定檔名,grep 將從標準輸入讀取資料。

2、常用選項

  • -i:忽略大小寫。
  • -v:反向選擇,只顯示不匹配的行。
  • -c:計算匹配的行數,而不是顯示行內容。
  • -l:只列出包含匹配文字的檔名,而不顯示匹配的行。
  • -n:顯示匹配的行號。
  • -r 或 -R:遞迴搜尋子目錄中的檔案。
  • -E:使用擴充套件的正規表示式。
  • -F:將模式作為固定字串處理,而不是正規表示式。
  • -o:只輸出匹配的部分,而不是整行。
  • -A 數字:顯示匹配行以及之後的幾行。
  • -B 數字:顯示匹配行以及之前的幾行。
  • -C 數字:顯示匹配行以及上下文的幾行。

3、示例

1)基本語法

grep pattern file.txt

2)忽略大小寫

grep -i pattern file.txt

3)顯示行號

grep -n pattern file.txt

4)遞迴搜尋所有子目錄

grep -rnw '/path/to/directory' -e 'pattern'

5)只顯示檔名

grep -l pattern *.txt

6)只顯示匹配的行數

grep -c pattern file.txt

7)匹配整個單詞

grep -w pattern file.txt

8)使用正規表示式

grep -E '\bword\b' file.txt

9)顯示上下文的幾行

grep -C 2 pattern file.txt

10)搜尋檔案中的所有“error”字串

grep "error" /var/log/syslog

11)搜尋當前目錄及子目錄下所有檔案中包含“function”的行,並顯示行號

grep -rn "function" .

12)計算檔案中包含“warning”的行數

grep -c "warning" file.txt

13)反向選擇,顯示不包含“debug”的所有行

grep -v "debug" file.txt

14)在多個檔案中查詢

grep "match_pattern" file_1 file_2 file_3 ...

15)標記匹配顏色 --color=auto 選項

grep "match_pattern" file_name --color=auto

16)使用正規表示式 -E 選項

grep -E "[1-9]+"
或
egrep "[1-9]+"

17)只輸出檔案中匹配到的部分 -o 選項

[root@localhost ~]# echo this is a test line. | grep -o -E "[a-z]+\."
line.
[root@localhost ~]# echo this is a test line. | egrep -o "[a-z]+\."
line.

18)統計檔案或者文字中包含匹配字串的行數 -c 選項

grep -c "text" file_name

19)輸出包含匹配字串的行數 -n 選項

grep "text" -n file_name
或
cat file_name | grep "text" -n

#多個檔案
grep "text" -n file_1 file_2

20)搜尋多個檔案並查詢匹配文字在哪些檔案中

grep -l "text" file1 file2 file3...

4、grep遞迴搜尋檔案

1)在多級目錄中對文字進行遞迴搜尋

grep "text" . -r -n
# .表示當前目錄

2)忽略匹配樣式中的字元大小寫

[root@localhost ~]# echo "hello world" | grep -i "HELLO"
hello world

3)選項 -e 制動多個匹配樣式

[root@localhost ~]# echo this is a text line | grep -e "is" -e "line" -o
is
is
line
#也可以使用-f選項來匹配多個樣式,在樣式檔案中逐行寫出需要匹配的字元。
[root@localhost myfolder]# cat patfile
aaa
bbb
[root@localhost myfolder]# echo aaa bbb ccc ddd eee | grep -f patfile -o
aaa
bbb

4)在grep搜尋結果中包括或者排除指定檔案

#只在目錄中所有的.php和.html檔案中遞迴搜尋字元"main()"
grep "main()" . -r --include *.{php,html}

#在搜尋結果中排除所有README檔案
grep "main()" . -r --exclude "README"

#在搜尋結果中排除filelist檔案列表裡的檔案
grep "main()" . -r --exclude-from filelist

5)grep靜默輸出

grep -q "test" filename
#不會輸出任何資訊,如果命令執行成功返回0,失敗則返回非0值。一般用於條件測試。

6)列印出匹配文字之前或者之後的行

#顯示匹配某個結果之後的3行,使用 -A 選項:
[root@localhost myfolder]# seq 10 | grep "5" -A 3
5
6
7
8

#顯示匹配某個結果之前的3行,使用 -B 選項:
[root@localhost myfolder]# seq 10 | grep "5" -B 3
2
3
4
5

#顯示匹配某個結果的前三行和後三行,使用 -C 選項:
[root@localhost myfolder]# seq 10 | grep "5" -C 3
2
3
4
5
6
7
8

#如果匹配結果有多個,會用“--”作為各匹配結果之間的分隔符:
[root@localhost myfolder]# echo -e "a\nb\nc\na\nb\nc" | grep a -A 1
a
b
--
a
b

三、sed命令

sed 是一種線上編輯器,它一次處理一行內容。處理時,把當前處理的行儲存在臨時緩衝區中,稱為“模式空間”(pattern space),接著用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往螢幕。接著處理下一行,這樣不斷重複,直到檔案末尾。檔案內容並沒有改變,除非你使用重定向儲存輸出。Sed主要用來自動編輯一個或多個檔案;簡化對檔案的反覆操作;編寫轉換程式等。

1、基本語法

sed [選項]... '{命令}' [輸入檔案]...
  • 選項:控制sed的行為,如-i直接修改檔案內容,-e允許多個編輯命令等。
  • 命令:用單引號括起來,指定要對文字執行的操作。
  • 輸入檔案:指定sed要處理的檔案。如果未指定檔案,sed將從標準輸入讀取資料。

2、常用選項

  • -e:新增一個編輯命令。
  • -f:從檔案中讀取編輯命令。
  • -i:直接修改檔案內容。
  • -n:抑制預設輸出,只輸出被明確指定的行。
  • -r:啟用擴充套件正規表示式支援。
  • -u:以原子方式更新檔案(與 -i 一起使用)。

3、命令格式

sed 命令的基本格式是:

[address][,address] command
  • address:可以是行號或正規表示式,用於指定命令作用的範圍。
  • command:要執行的操作。

4、常用命令

  • p:列印匹配的行。
  • d:刪除匹配的行。
  • s:替換文字。
  • i:在指定行之前插入文字。
  • a:在指定行之後追加文字。
  • c:替換匹配的行。

5、示例

1)列印檔案的前幾行

sed -n '1,5p' filename

-n選項和p命令一起使用,僅列印被p命令指定的行(這裡是前1~5行)。

2)刪除檔案中的空行

sed '/^$/d' filename

使用正規表示式/^$/匹配空行,d命令刪除這些行。

3)替換文字

sed 's/old/new/g' filename

將檔案中的"old"替換為"new"。g標誌表示全域性替換(即每行中的所有匹配項)。

4)直接修改檔案(危險動作,注意確認)

sed -i 's/old/new/g' filename

-i選項允許sed直接修改檔案內容,而不是輸出到標準輸出。

5)在特定行之前或之後插入文字

sed '3i\New line' filename  # 在第3行之前插入"New line"  
sed '3a\New line' filename  # 在第3行之後追加"New line"

6)替換整行

sed '3c\This is a new line' filename

將第3行替換為"This is a new line"。

7)替換字串並儲存結果

sed -i 's/pattern/replacement/g' file.txt

這將直接修改 file.txt 檔案中的內容。

8)讀取多個檔案並應用相同的編輯

sed 's/pattern/replacement/g' file1.txt file2.txt

9)使用多個編輯命令

sed -e 's/pattern1/replacement1/g' -e 's/pattern2/replacement2/g' file.txt

10)使用行號指定編輯範圍

sed '1,10 s/pattern/replacement/g' file.txt

11)以行為單位的新增/刪除

將 ./file 的內容列出並且列印行號,同時刪除2~5行內容:

[root@localhost myfolder]# nl ./file | sed '2,5d'
     1  11
     6  66
     7  77
     8  88
     9  99
......

因為2~5行內容被刪除了,所以就不顯示2~5行的內容了。

只要刪除第 2 行:

[root@localhost myfolder]# nl ./file | sed '2d'
     1  11
     3  33
     4  44
     5  55
     6  66
......

要刪除第 10 到最後一行:

[root@localhost myfolder]# nl ./file | sed '10,$d'
     1  11
     2  22
     3  33
     4  44
     5  55
     6  66
     7  77
     8  88
     9  99

在第2行後面加上[drink tea]字樣:

[root@localhost myfolder]# nl ./file | sed '2a drink tea'
     1  11
     2  22
drink tea
     3  33
     4  44
     5  55
     6  66
     7  77
     8  88
     9  99
......

在第2行前面加上[drink tea]字樣:

[root@localhost myfolder]# nl ./file | sed '2i drink tea'
     1  11
drink tea
     2  22
     3  33
     4  44
     5  55
     6  66
     7  77
......

如果要增加兩行以上,例如:[Drink tea or …..]與[drink beer?]:

[root@localhost myfolder]# nl ./file | sed '2a Drink tea or ......\
> drink beer?'
     1  11
     2  22
Drink tea or ......
drink beer?
     3  33
     4  44
     5  55
...省略...

每一行之間都必須要以反斜槓“\”來進行新行的新增。

12)以行為單位的替換與顯示

將第2~5行的內容替換為[No 2~5]:

[root@localhost myfolder]# nl ./file | sed '2,5c No 2~5'
     1  11
No 2~5
     6  66
     7  77
     8  88
......

透過這個方法我們就能夠將資料整行取代了!

僅列出 ./file 檔案內的第 5~7 行內容:

[root@localhost myfolder]# nl ./file | sed -n '5,7p'
     5  55
     6  66
     7  77

13)資料的搜尋並顯示

搜尋 ./file 有aa關鍵字的行,並且只輸出匹配的行:

[root@localhost myfolder]# nl ./file | sed -n '/aa/p'
    17  aa
    32  dsaaaaaaaaaassdasdassdadadssdasdasd3213213213
    37  Gaaa
    59  aaaaa

其中使用-n表示只列印匹配的行。

14)資料的搜尋並刪除

刪除 ./file 所有包含“22”的行,其他行輸出:

[root@localhost myfolder]# nl ./file | sed '/22/d'
     1  11
     3  33
     4  44
     5  55
     6  66
......

15)資料的搜尋並執行命令

搜尋 ./file 檔案找到root對應的行,執行後面花括號中的一組命令,每個命令之間用分號分隔,這裡把 test 替換為 testNew,再輸出這行:

[root@localhost myfolder]# nl ./file | sed -n '/root/{s/test/testNew/;p}'
    32  testNew admin root

如果只替換 ./file 的第一個 test 關鍵字為 testNew ,就退出:

[root@localhost myfolder]# nl ./file | sed -n '/test/{s/test/testNew/;p;q}'
    32  testNew admin root

最後的q表示退出。

16)資料的搜尋並替換

除了整行的處理模式之外,sed 還可以用行為單位進行部分資料的搜尋並取代。基本上 sed 的搜尋、替代與 vi 類似:

sed 's/要被取代的字串/新的字串/g'

四、awk命令

awk是行處理器:相比較螢幕處理的優點,在處理大檔案時不會出現記憶體溢位或是處理緩慢的問題,通常用來格式化文字資訊。

awk處理過程:依次對每一行進行處理,然後輸出。

1、基本語法

awk [options] 'pattern {action}' [filename]
  • options:命令列選項,用於控制awk的工作方式。這些選項包括設定欄位分隔符、定義變數等。
  • pattern:模式匹配,用於指定哪些行或記錄需要被處理。模式可以是正規表示式、條件表示式或布林表示式。如果省略pattern,則對所有行執行action。
  • action:當模式匹配成功時,需要執行的命令或語句。這些命令或語句可以是內建的awk命令,也可以是自定義的程式碼塊。
  • filename:指定要處理的檔名。如果省略,則預設從標準輸入讀取。

2、常用選項

  • -F fs 或 --field-separator=fs:設定欄位分隔符,預設為空格。
  • -v var=val 或 --assign=var=val:定義變數及其初始值。
  • -f script-file 或 --file=script-file:從檔案中讀取awk指令碼。
  • -i inplace 或 --inplace:直接在原檔案上修改(注意:這個選項在GNU awk中可能不被支援,需要使用其他工具如sed實現)。
  • -n 或 --non-decimal-data:允許非十進位制數被識別。
  • -W interactive 或 --interactive:以互動模式執行。

3、指令碼語法

awk 指令碼通常由模式(pattern)和動作(action)組成。基本形式為:

pattern { action }
  • pattern:一個表示式,如果為真,則執行 action。
  • action:一組要執行的命令。

如果省略 pattern,則預設為 true,意味著 action 將應用於每一行。

4、內建變數

awk 提供了一些內建變數來簡化指令碼編寫:

  • ARGC:命令列引數的數量。
  • ARGV:命令列引數的陣列。
  • ENVIRON:環境變數的陣列。
  • FILENAME:當前檔名。
  • FNR:當前檔案中的記錄編號。
  • FS:欄位分隔符。
  • NF:當前記錄中的欄位數量。
  • NR:所有處理過的記錄總數。
  • OFS:輸出欄位分隔符。
  • ORS:輸出記錄分隔符。
  • RS:輸入記錄分隔符。

5、函式

awk 提供了多種內建函式來處理文字和數值資料:

  • print:輸出資料。
  • printf:格式化輸出資料。
  • getline:從檔案中讀取一行。
  • split:分割字串到陣列。
  • gsub:全域性替換。
  • match:正規表示式匹配。
  • rand 和 srand:生成隨機數。
  • sqrt, exp, log, sin, cos, atan2:數學函式。
  • tolower 和 toupper:轉換字串為小寫或大寫。
  • length:返回字串長度。
  • index:返回子字串的位置。
  • substr:獲取子字串。
  • mktime:轉換日期字串為時間戳。

6、awk命令形式

awk [-F|-f|-v] 'BEGIN{} /pattern/ {command1;command2} END{}' [filename]
  • [-F|-f|-v] 大引數,-F指定分隔符,-f呼叫指令碼,-v定義變數 var=value
  • ' ' 引用程式碼塊
  • BEGIN 初始化程式碼塊,在對每一行進行處理之前,初始化程式碼,主要是引用全域性變數,設定FS分隔符
  • /pattern/ 匹配程式碼塊,可以是字串或正規表示式
  • {} 命令程式碼塊,包含一條或多條命令
  • ; 多條命令使用分號分隔
  • END 結尾程式碼塊,在對每一行進行處理之後再執行的程式碼塊,主要是進行最終計算或輸出結尾摘要資訊
  • [filename] 需要處理的檔案

7、特殊要點

$0 表示整個當前行
$1 每行第一個欄位
$n 當前記錄的第n個欄位,欄位間由FS分隔
NF 欄位數量變數
NR 每行的記錄號,多檔案記錄遞增
FNR 與NR類似,不過多檔案記錄不遞增,每個檔案都從1開始
\t 製表符
\n 換行符
FS BEGIN時定義分隔符(預設是任何空格)
RS 輸入的記錄分隔符, 預設為換行符(即文字是按一行一行輸入)
~ 匹配,與==相比不是精確比較
!~ 不匹配,不精確比較
== 等於,必須全部相等,精確比較
!= 不等於,精確比較
&& 邏輯與
|| 邏輯或
OFS 輸出欄位分隔符, 預設也是空格,可以改為製表符等
ORS 輸出的記錄分隔符,預設為換行符,即處理結果也是一行一行輸出到螢幕
-F'[:#/]' 定義三個分隔符

8、示例

1) 列印所有行

awk '{print}' file.txt

2)列印特定列

awk '{print $1}' file.txt  # 列印第一列

3)計算總和

awk '{sum += $1} END {print sum}' numbers.txt

4)過濾特定模式

awk '/pattern/ {print}' file.txt

5)使用多個模式

awk '/pattern1/ || /pattern2/ {print}' file.txt

6)自定義分隔符

awk -F: '{print $1}' /etc/passwd  # 使用冒號作為分隔符,列印/etc/passwd檔案的第一列(使用者名稱)

9、注意事項

  • awk預設按行處理文字,並使用空格作為欄位分隔符。
  • awk支援變數定義、流程控制(如if、else、for、while)、數學函式和字串函式等高階功能。
  • awk還提供了BEGIN和END兩個特殊的模式塊,BEGIN塊在讀取任何輸入行之前執行,END塊在讀取完所有輸入行之後執行。
  • awk中的$0代表整行文字,$1、$2、$3...代表第一個、第二個、第三個欄位等。
  • awk還包含一些內建變數,如NR(當前記錄號,即行號)、NF(當前記錄的欄位數,即每行的列數)等。

這些只是 awk 基礎使用的冰山一角。awk 的功能非常強大,可以編寫複雜的指令碼來處理各種各樣的任務。

此文由博主精心撰寫轉載請保留此原文連結:https://www.cnblogs.com/xyh9039/p/18337347

版權宣告:如有雷同純屬巧合,如有侵權請及時聯絡本人修改,謝謝!!!

相關文章