正則表達式
符號 |
含義 |
. |
匹配任意ASCII中任意單個字符,或是字母,或是數字 |
^ |
匹配行首 |
$ |
匹配行尾 |
* |
匹配任意字符或前一個的一次或多次重復 |
\ |
轉義,被轉義的有$ . ‘ “ * [ ] ^ \ ( ) | + ? |
[…] [-] |
匹配一個范圍或集合 |
\{\} |
匹配n次:\{n\},最少n次:\{n,\},m到n次:\{m,n\}, |
+ |
僅用於awk,標識匹配一個或多個 |
? |
僅用於awk,匹配0次或1次 |
grep
先給出示例文件data.f的內容
48 Dec 3BC1977 LPSX 68.00 LVX2A 138 483 Sept 5AP1996 USP 65.00 LVX2C 189 47 Oct 3ZL1998 LPSX 43.00 KVM9D 512 219 dec 2CC1999 CAD 23.00 PLV2C 68 484 nov 7PL1996 CAD 49.00 PLV2C 234 483 may 5PA1998 USP 37.00 KVM9D 644 216 sept 3ZL1998 USP 86.00 KVM9E 234
grep一般匹配
一般匹配通常需要將匹配的模式使用雙引號括起來。
grep的一般格式為:grep [選項] 基本正則表達式 [文件]
注意對輸入的參數字符串使用雙引號
grep的選項:
-c 只輸出匹配行的數量
-i 不區分大小寫(只適用於單字符)
-h 查詢多文件時,不顯示文件名
-l 查詢多文件時,只輸出包含匹配字符的文件名
-n 顯示匹配行的行號
-s 不顯示不存在或無匹配文本的錯誤信息
-v 顯示不包含匹配文本的所有行
查詢多個文件:可以使用文件占位符查詢多個文件,也可以將多個文件列出,如:
grep "45" data*.f
grep "45" data1.f data2.f
全字匹配:在匹配的字符后邊加上\>
grep "45\>" data.f
grep使用正則匹配
為了防止shell的替換等其他行為發生,使用時通常使用單引號。
模式范圍:grep '48[43]' data.f,匹配484/483
不匹配行首:grep '^[^48]' data.f
先匹配月份,再匹配模式:grep '[Ss]ept' data.f | grep 443
空行:grep '^$' data.f
擴展模式:
使用-E參數,這一擴展允許使用擴展模式匹配
匹配219或者216:grep -E '219|216' data.f
類名
類名 |
等價的正則 |
|
類名 |
等價的正則 |
[[:upper:]] |
[A-Z] |
|
[[:alnum:]] |
[0-9a-zA-Z] |
[[:lower:]] |
[a-z] |
|
[[:space:]] |
空格或tab鍵 |
[[:digit:]] |
[0-9] |
|
[[:alpha:]] |
[a-zA-Z] |
grep '[[:alpha:]]*' data.f
系統grep命令
目錄:ls -l grep '^d'
passwd文件:grep "angel" /etc/passed
查看DNS服務進程(通常為named):ps | grep "named"
egrep
expression或extended grep,接受所有的正則表達式,特點為:
- 文件作為查詢的正則字符串。egrep -f grepstrings data.f
- 使用 | 符號,表示匹配兩邊之一
- 使用 ^ 符號,表示不匹配到。
AWK進行文本過濾
Usage: awk [POSIX or GNU style options] -f progfile file ...
Usage: awk [POSIX or GNU style options] 'program' file ...
其中progfile中或者'program'是真正的AWK命令,最后的file是輸入文件(s)。
常用的參數是-F field-separator,指定文件分隔符,默認為空白字符。對於passed之類的使用冒號分割的,則使用-F:參數,表示冒號為列分割。
同樣可以使得同sh腳本一樣,在首行指定#/bin/awk,可以使腳本文件使用AWK進行執行。
awk腳本
awk腳本由各種操作和模式組成。
awk將每次讀取一行,然后使用分隔符將每一行分割成多個域。
awk語句都由模式和動作組成,模式決定動作的觸發條件,如果省略模式部分,動作將時刻保持執行。
awk模式,包括兩個特殊字段,BEGIN和END。BEGIN使用在瀏覽文本動作前,之后文本瀏覽動作開始執行。END使用在瀏覽文本動作之后,打印輸出文本總數和結尾狀態標識。如不特殊指明,總是匹配或打印行數。
awk動作,在大括號{}內指明,多數用來打印,還有諸如if和循環語句等。如不特殊指明,將打印所有瀏覽出來的記錄。
域:awk執行動作時,將域標記為$1 $2 $3 ...,其中$0標識所有域。
記錄:每一行就是一個記錄
提取文件中的每一列
awk '{print $0}' data.f
awk '{print $3}' data.f
添加文件頭尾
awk 'BEGIN {print "Month\tPrice\n------------------------"} {print $2"\t"$5} END {print "------------------\ntip: end of file"}' data.f
awk中的正則表達式
awk中使用正則時,是使用//括起來。如:/wang*/
條件操作符
操作符 |
描述 |
操作符 |
描述 |
|
< |
小於 |
>= |
大於等於 |
|
<= |
小於等於 |
~ |
匹配正則表達式 |
|
== |
等於 |
!~ |
不匹配正則表達式 |
|
!= |
不等於 |
&& | 且 | |
|| |
或 |
! | 非 |
打印符合條件的行的部分列: awk '{if($4~/LPSX/) print $2"\t"$4"\t"$5}' data.f
打印不符合條件的行的部分列: awk '{if($4!~/LPSX/) print $2"\t"$4"\t"$5}' data.f
打印第一列小於第七列的:awk '{if($1 < $7) print $1"\t"$4"\t"$7}' data.f
awk內置變量
ARGC 命令行參數個數
ARGV 命令行參數排列
ENVIRON 支持隊列中系統環境變量的使用
FILENAME awk瀏覽的文件名
FNR 瀏覽文件的記錄數
FS 設置輸入域分隔符,等價於命令行-F選項
NF 瀏覽記錄的域個數
NR 已讀的記錄數
OFS 輸出域分隔符
ORS 輸出記錄分隔符
RS 控制記錄分隔符
打印記錄號,域個數,最后打印文件名稱
awk '{print NF"\t"NR"\t"$0} END {print FILENAME}' data.f
awk操作符
賦值操作:=、+=、*=、/=、%=、^=
條件表達式:?
或且非:||、&&、!
匹配:~、!~
關系:<、<=、>、>=、!=、==
算術:+、-、*、/、%、^
前后綴:++、--
使用變量:awk '{name=$4; price=$5;print name"\t"price} ' data.f
內置字符串函數
gsub(r,s) |
在整個$0中用s替代r |
gsub(r,s,t) |
在整個t中用s替代r |
index(s,t) |
返回s中字符串t的第一位置 |
length(s) |
返回s長度 |
match(s,r) |
測試s是否包含匹配r的字符串 |
split(s,a,fs) |
在fs上將s分成序列a |
sprint(fmt,exp) |
返回經fmt格式化后的exp |
sub(r,s) |
用$0中最左邊最長的子串代替s |
substr(s,p) |
返回字符串s中從p開始的后綴部分 |
substr(s,p,n) |
返回字符串s中從p開始長度為n的后綴部分 |
返回每行的長度:awk '{print $0"\t"length($0)} ' data.f
awk使用printf修飾輸出格式
修飾符 |
含義 |
- |
左對齊 |
Width |
域的步長,用0表示0步長 |
.prec |
最大字符串長度,或小數點右邊的位數 |
%c |
ASCII字符 |
%d |
整數 |
%e |
浮點數,科學記數法 |
%f |
浮點數,例如(123.44) |
%g |
awk決定使用哪種浮點數轉換e或者f |
%o |
八進制數 |
注意printf不會自動輸出換行。
對ASCII的65輸出字符A:awk 'BEGIN {printf "%c\n",65}'
固定列寬輸出:awk '{printf "%-15s %s\n",$1,$3}' data.f
awk腳本文件
如下是一個腳本文件
第一行表示執行腳本的命令和參數,!/bin/awk -f
執行時,鍵入腳本名稱和輸入文件即可得到輸出
awk數組
使用實例:
- 將文本划分到數組:awk 'BEGIN {print split("123:456:789",array,":")}'
得到的數組為:array[1]="123"等。 - 循環:For (element in array) print array[element]
awk執行Shell
awk 'BEGIN{cmd="echo shell_cmd"; system(cmd); close(cmd);}'
awk 'BEGIN{cmd="echo shell_cmd"; cmd | getline output; close(cmd); print output}'
sed
sed [選項] sed命令 輸入文件
sed [選項] -f sed腳本文件 輸入文件
給出一個文本的例子quota.txt:
The honeysuckle hand played all night long for only $90.
It was an evening of splendid music and company.
Too bad the disco floor fell through at 23:10.
The local nurse Miss P.Neave was in attendance.
選項包括:
- n,不打印所編輯的行到標准輸出
- c,下一命令是編輯命令,如果只有一條sed命令,則不必須指定
- f,指定sed腳本文件
定位到文本所在的行:
x |
x為一行號,如1,$表示最后一行 |
x,y |
表示行號范圍從x到y,如2,5表示從第2行到第5行 |
/pattern/ |
查詢包含模式的行。例如/disk/或/[a-z]/ |
/pattern/pattern/ |
查詢包含兩個模式的行。例如/disk/disks/ |
/pattern/,x |
在給定行號上查詢包含模式的行。如/ribbon/,3 |
x,/pattern/ |
通過行號和模式查詢匹配行。3./vdu/ |
x,y! |
查詢不包含指定行號x和y的行。1,2! |
基本的sed編輯命令
p |
打印匹配行 |
= |
顯示文件行號 |
a\ |
在定位行號后附加新文本信息 |
i\ |
在定位行號前插入新文本信息 |
d |
刪除定位行 |
c\ |
用新文本替換定位文本 |
s |
使用替換模式替換相應模式 |
r |
從另一個文件中讀文本 |
w |
寫文本到一個文件 |
q |
第一個模式匹配完成后推出或立即推出 |
l |
顯示與八進制ASCII代碼等價的控制字符 |
{} |
在定位行執行的命令組 |
n |
從另一個文件中讀文本下一行,並附加在下一行 |
g |
將模式2粘貼到/patternn/ |
y |
傳送字符 |
n |
延續到下一輸入行;允許跨行的模式匹配語句 |
使用示例
- 顯示指定行(由於默認會打印所有編輯的行到輸出,所以使用n參數):sed -n '2p' quote.txt
- 打印指定范圍的行:sed -n '1,3p' quote.txt
- 打印符合模式的行:sed -n '/Neave/'p quote.txt
- 混合行號與模式:sed -n '4,/Neave/'p quote.txt
- 匹配元字符,使用轉義:sed -n '/\$/'p quote.txt
- 打印行號:sed -n '/music/=' quote.txt
如果不加-n,則會先打印編輯的行,再打印匹配到行的行號。 - 替換命令:sed '1,5s/night/NIGHT/' quote.txt
替換1到5行中第一次出現的neight成為NIGHT
替換還能跟gpwn四個選項中的一個。g替換所有/默認替換一次;p打印所有輸出結果;w輸出到一個文件,需要跟輸出文件參數(注意同屬於sed命令這個參數)。
腳本文件的編寫
如下腳本文件,對給的示例數據執行:
#!/bin/sed -f /company/ a\ Then suddenly it happened.
執行后的結果為:
shuf
隨機對輸入行重新排列