shell 中 grep、sed、awk 命令

FreeeLinux發表於2017-03-14

grep 命令

grep命令基本語法

grep命令是列印匹配文字行,其全稱為 Global Search Regular Expression and Print out the line;基本語法如下:

grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

其中,OPTIONS表示選項;PATTERN表示匹配模式,匹配模式可以是字串、變數、正規表示式,若匹配模式中含義空格,則需要使用雙引號將匹配模式引起來;FILE表示一系列檔案;grep命令從檔案中搜尋滿足指定匹配模式的文字行,並列印出來。

在前面文章《正規表示式》可知,正規表示式的分類為:

  • 基本正規表示式(Basic Regular Expression):Basic RegEx,簡稱 BRE
  • 擴充套件正規表示式(Extended Regular Expression):Extended RegEx,簡稱 ERE
  • Perl 正規表示式(Perl Regular Expression):Perl RegEx,簡稱 PCRE

grep命令根據不同的引數支援不同的正規表示式:

  • grep命令後不跟任何引數(預設),則表示要使用“BRE”;
  • grep命令後跟-E引數,則表示要使用“ERE”;
  • grep命令後跟-P引數,則表示要使用“PCRE”;

常用OPTIONS選項如下表所示:

選項 說明
-E 指定 PATTERN 匹配模式為擴充套件正規表示式
-F 指定 PATTERN 匹配模式為固定的字串
-G 指定 PATTERN 匹配模式為基本正規表示式
-P 指定 PATTERN 匹配模式為 Perl 正規表示式
   
-e PATTERN 指定 PATTERN 為一個或多個搜尋模式
-f FILE 指定包含搜尋模式的 FILE
-i 匹配是忽略字母大小寫
-v 顯示所有與匹配模式不匹配的文字行
-w 執行單詞搜尋
-x 顯示與指定模式精確匹配而不含其他字元的文字行
-y 與選項 -i 相同功能
   
-c 只列印匹配的文字行的行數,不顯示匹配內容
-l 只顯示匹配文字行的檔名,不顯示匹配內容
-n 列出所有匹配的文字行,並顯示行號
-r 遞迴搜尋目錄(當前目錄及其各級子目錄)
-s 不顯示錯誤資訊

流編輯器 sed

sed命令

sed命令從檔案或者標準輸入中一次讀取一行資料,將該行資料複製到緩衝區,然後讀取命令列或指令碼的編輯子命令,對緩衝區中的文字行進行編輯。重複此工作,直到所有文字行都處理完畢。

sed命令編輯的是檔案是原始檔案在緩衝區中的副本,並不影響原始檔案,但是可以把編輯結果通過輸出重定向儲存起來。

sed命令的基本語法如下所示:

sed [OPTION]... {script} [input-file]...
  • 1
  • 1

常用選項OPTION如下表所示:

選項 說明
-n 取消預設輸出
-e script 允許執行多個指令碼
-f script-file 從指令碼檔案中讀取命令
-i 直接修改原始檔案
-l N 指定行長度為 N
-r 在指令碼中使用擴充套件正規表示式
-s 把檔案作為單獨檔案
-u 最低限度的快取輸入與輸出

文字行定位

sed命令提供了兩種方式來實現文字行的定位:行號定位正規表示式定位

行號定位

  • 定位某個特定的行nn是一個整數,表示定位到文字的第n行;
  • 定位某段連續的行n,mnm都是整數,表示定位到起始行為n,終止行為m的文字行;
  • 指定起始行和步長start~step:起始行為start,步長為step
  • 第一行1和最後一行$1表示第一行,$表示最後一行;
  • 指定某行後面的幾行n,+x:表示從第n行開始到後面的x行;

正規表示式定位

sed命令使用正規表示式定位文字行的語法如下所示:

#regexp 表示正規表示式
/regexp/
  • 1
  • 2
  • 1
  • 2

sed命令的常用操作

sed命令的常用編輯命令有:列印、刪除、增加、替換;其基本語法如下所示:

[address1[,address2]] command [argument]
  • 1
  • 1

其中address稱為位置引數,即上面的行定位;commandsed所提供的子命令,用來實現編輯操作;argument表示子命令的選項引數;

列印文字

sed命令中可通過位置引數和p命令列印所需要的文字行,其語法如下所示:

[address1[,address2]] p
  • 1
  • 1

例如:

#! /bin/bash

#輸出第1~4行文字,注意1,3p之間是單引號
sed -n '1,3p' test.txt

#輸出以Lin開頭的文字行
result=`sed -n '/^Lin/ p' test.txt`
echo "$result"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

替換文字

sed命令中可通過位置引數和s子命令替換文字行,其語法如下所示:

[address1[,address2]] s/pattern/replacemen/[flag]
  • 1
  • 1

flag為替換標誌,不同值會影響s子命令的行為;flag常用取值如下表所示:

取值 說明
g 全域性匹配,會替換文字行所有符合規則的字串
p 替換第一個符合規則的字串,並將緩衝區輸出到標準輸出
w 替換第一個符合規則的字串,並將受影響的行輸出到磁碟檔案中
十進位制數n 替換文字行中第n個符合規則的字串
若不指定flag值,替換文字行中第一個符合規則的字串

刪除文字

sed命令中可通過位置引數和d子命令刪除文字行,其語法如下所示:

[address1[,address2]] d
  • 1
  • 1

增加文字

追加文字 
sed命令中可通過位置引數和a子命令追加文字行,其語法如下所示:

#將string插入到address1位置後面
[address1] a string 
  • 1
  • 2
  • 1
  • 2

插入文字 
sed命令中可通過位置引數和i子命令插入文字行,其語法如下所示:

#將string插入到address1位置前面
[address1] i string 
  • 1
  • 2
  • 1
  • 2

組合命令

sed命令支援將多個子命令組合在一起使用;具體方式如下所示:

  • 使用-e選項:-e選項可以將多個子命令組合在一起使用;例如:
#! /bin/bash

#將全部小寫字母 e 替換成大寫字母 E,並列印第 1 行到第 3 行文字行
result=`sed -n -e 's/e/E/g' -e '1,3 p' test.txt`
echo "$result"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 使用分號;執行多個子命令: 
    其語法格式:
sed -e 'command1; command2...' filename
  • 1
  • 1

例如:

#! /bin/bash

#將全部小寫字母 e 替換成大寫字母 E,並列印第 1 行到第 3 行文字行
result=`sed -n -e 's/e/E/g; 1,3 p' test.txt`
echo "$result"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 對同一個地址使用多個子命令: 
    其語法格式:
address{
    command1
    command2
    command3
    ...
}
#或
[address] { command1;command2;command3;...}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

sed指令碼檔案

可以將多個子命令寫成字尾名為.sedsed指令碼檔案,sed指令碼檔案內容只需將各個子命令依次列出來,不必使用引號,若將多個子命令寫在同一行,則不同子命令之間需使用分號隔開。呼叫sed指令碼檔案的格式如下:

sed -f script
  • 1
  • 1

awk命令

awk命令的基本語法

awk命令是一個文字處理工具,其基本語法如下所示:

awk pattern { actions }
  • 1
  • 1

其中,pattern表示匹配模式,actions表示要執行的操作;即對符合pattern匹配模式的文字行執行actions操作;若省略pattern匹配模式,則表示對所有文字行執行actions操作;若省略pattern 
匹配模式,則把匹配成功的文字行列印輸出;但是不能同時省略patternactions

pattern匹配模式可以是以下其中一種:

  • 正規表示式;
  • 關係表示式;
  • 模式1,模式2:指定一行的範圍;
  • BEGIN:指定在第一行文字被處理之前所發生的操作;
  • END:指定在最後一行文字被讀取之後傳送的操作;

actions命令由一個或多個命令、函式或者表示式組成,他們之間由換行符或分號隔開,並位於大括號內,一般有以下四種情況:

  • 變數或陣列賦值;
  • 輸出命令,例如printfprint
  • 內建函式;
  • 流控制語句,例如ifwhilefor語句;

awk命令的執行方式:

  • 通過命令列執行:其語法:
awk 'awk程式語句' 資料檔案
  • 1
  • 1
  • 執行 awk指令碼:其語法:
#注意:awk指令碼檔案是字尾名為.awk的檔案
awk -f awk指令碼檔案 資料檔案
  • 1
  • 2
  • 1
  • 2
  • 可執行指令碼檔案:即在 shell檔案中指定解析器為#! /bin/awk -f

awk命令的匹配模式

awk命令的匹配模式主要包括:關係表示式、正規表示式、混合模式、區間模式、BEGIN模式、END模式等。

關係表示式

awk命令中的關係運算子如下表所示:

運算子 說明
> 大於
>= 大於等於
< 小於
<= 小於等於
== 等於
!= 不等於
~ 匹配運算:例如$1~/^A表示匹配第一個欄位以字元A開頭的記錄
!~ 不匹配運算

正規表示式

awk支援以正規表示式為匹配模式,其基本語法如下所示:

#regexp 表示正規表示式
/regexp/
  • 1
  • 2
  • 1
  • 2

例如:輸出以字元u開頭的文字行

#! /bin/bash
#filename:test.sh

result=`awk '/^u/ {print}' shell.md`

echo "$result"

#輸出結果:
$ sh test.sh 
unset variable_name
unset var
until
until
unset -f 函式名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

混合模式

awk命令的匹配模式中,可以通過邏輯運算子使用多個表示式組成命令;基本邏輯運算子如下表所示:

運算子 說明
&& 邏輯與
|| 邏輯或
! 邏輯非

區間模式

awk命令支援區間模式,其語法如下:

pattern1, pattern2
  • 1
  • 1

例如:第一個匹配模式是:以字串one開頭的文字行;第二個匹配模式是:第3欄位等於14的文字行;所有符合這兩個匹配模式之間的文字行都會被輸出;

#!/bin/bash
#filename:test.sh

result=`awk '/^one/ , $3==14 {print}' test.txt`

echo "$result"

#執行結果:
$ sh test.sh 
one     10  20  30
two     15  25  20
three   20  15  31
four    16  26  35
five    11  14  40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

BEGIN模式

BEGIN模式是awk命令一種特殊的內建模式,在awk讀取資料之前對執行的操作;

例如:


#! /usr/bin/awk -f
#filename:test.sh

BEGIN { print "Beging operator." }
/^one/ , $3==14 {print}

#執行結果:
$ ./test.sh test.txt
Beging operator.
one     10  20  30
two     15  25  20
three   20  15  31
four    16  26  35
five    11  14  40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

END模式

END模式是在處理完資料之後執行的操作;例如:

#! /usr/bin/awk -f
# /usr/bin/env awk -f
#filename:test.sh

BEGIN {
    print "Beging operator."
    print "===================="
}
/^one/ , $3==14 {print}

END {
    print "===================="
    print "Ending operator."
}


#執行結果:
$ ./test.sh test.txt
Beging operator.
====================
one     10  20  30
two     15  25  20
three   20  15  31
four    16  26  35
five    11  14  40
====================
Ending operator.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

awk 變數

awk中的使用者自定義的變數一般在BEGIN模式中定義;

系統內建變數

awk的常用系統內建變數如下表所示:

變數 說明
$0 當前記錄(存放著整個行的內容)
$1~$n 當前記錄的第n個欄位,欄位間由FS分隔
FS 輸入欄位分隔符 預設是空格或Tab
NF 當前記錄中的欄位個數,就是有多少列
NR 已經讀出的記錄數,就是行號,從1開始,如果有多個檔案話,這個值也是不斷累加中
FNR 當前記錄數,與NR不同的是,這個值會是各個檔案自己的行號
RS 輸入的記錄分隔符, 預設為換行符
OFS 輸出欄位分隔符, 預設也是空格
ORS 輸出的記錄分隔符,預設為換行符
FILENAME 當前輸入檔案的名字

運算子

awk命令支援常用的運算子:算術運算子、賦值運算子、條件運算子、邏輯運演算法、關係運算子等操作;

算術運算子

awk命令直接支援的算術運算子有:加+、減-、乘*、除/、模運算%、指數運算^;

賦值運算子

awk命令常用的賦值運算子有:=、+=、-=、*=、/=、%=、^=;

條件運算子

awk命令的條件運算子語法如下所示:

表示式?值1:值2
  • 1
  • 1

邏輯運演算法

awk命令支援的邏輯運算子:&&、||、!;

關係運算子

awk命令支援的關係運算子:>、>=、<、<=、==、!=、~、!~;

awk 函式

awk提供了許多系統函式,使用者也可以自定義函式;

字串函式

常用的字串函式有:

函式 說明
index(string1, string2) 返回 string2 在string1中第一次出現的位置
length(string) 返回string的長度
match(string,regexp) 返回string中符合regexp的子字串
split(string,array,seperator) 根據分隔符seperator,將字串string分隔成多個欄位,並儲存到陣列array中
sub(regexp,replacement,string) 將字串string第一個符合regexp的子字串替換成replacement
gsub(regexp,replacement,string) 將字串string中符合regexp的全部子字串都替換成replacement
substr(string,start,[length]) 從字串string的start位置開始擷取長度為length(若指定了length,否則一直擷取到字串string結束)字串

算術函式

常用的算術函式有:int(x)、sqrt(x)、exp(x)、log(x)、sin(x)、cos(x)、rand(x)、srand(x);

相關文章