awk的用法
a w k語言的最基本功能是在文件或字符串中基於指定規則瀏覽和抽取信息
調用awk
有三種方式調用a w k,
第一種是命令行方式,如:
awk –F : ‘commands’ input-files
第二種方法是將所有a w k命令插入一個文件,並使a w k程序可執行,然后用a w k命令作為腳本的首行,以便通過鍵入腳本名稱來調用它。
第三種方式是將所有的a w k命令插入一個單獨文件,然后調用:
awk –f awk-script-file input-files
awk腳本
模式和動作
在命令中調用a w k時,a w k腳本由各種操作和模式組成。模式包括兩個特殊字段B E G I N和E N D。
使用B E G I N語句設置計數和打印頭。B E G I N語句使用在任何文本瀏覽動作之前。E N D語句用來在a w k完成文本瀏覽動作后打印輸出文本總數和結尾狀態標志。
實際動作在大括號{ }內指明。
域和記錄
$ 0,意即所有域
• 確保整個a w k命令用單引號括起來。
• 確保命令內所有引號成對出現。
• 確保用花括號括起動作語句,用圓括號括起條件語句。
awk中的正則表達式
+ 使用+匹配一個或多個字符。
? 匹配模式出現頻率。例如使用/X Y?Z/匹配X Y Z或Y Z。
awk '{if($4~/Brown/) print $0}' tab2
等效於
awk '$0 ~ /Brown/' tab2
內置變量
awk '{print NF,NR,$0}END{print FILENAME}' tab1
NF 域的總數
NR已經讀取的記錄數
FILENAME
awk '{if(NR>0 && $2~/JLNQ/) print $0}END{print FILENAME}' tab1
顯示文件名
echo "/app/oracle/ora_dmp/lisx/tab1" | awk -F/ '{print $NF}'
定義域名
awk '{owner=$2;number=$3;if(owner~/SYSADMIN/ && number!=12101)print $0}END{print FILENAME}' tab1
awk 'BEGIN{NUM1=7}{if($1<=NUM1) print $0}END{print FILENAME}' tab1
當在a w k中修改任何域時,重要的一點是要記住實際輸入文件是不可修改的,修改的只是保存在緩存里的a w k復本
awk 'BEGIN{NUM1=7}{if($1<=NUM1) print $1+2,$2,$3+100}END{print FILENAME}' tab1
只打印修改部分:用{}
awk 'BEGIN{NUM1=7}{if($1<=NUM1){$2="ORACLE"; print $0}}END{print "filename:"FILENAME}' tab1
可以創建新的域
awk 'BEGIN{NUM1=7;print "COL1"tCOL2"tCOL3"tCOL4"}{if($1<=NUM1){$4=$1*$3;$2="ORACLE"; print $0}}END{print "filename:"FILENAME}' tab1
打印總數:
awk 'BEGIN{NUM1=7;print "COL1"tCOL2"tCOL3"tCOL4"}{if($1<=NUM1){tot+=$3;$4=$1*$3;$2="ORACLE"; print $0}}END{print "filename:"FILENAME "total col3:" tot}' tab1
使用此模式打印文件名及其長度,然后將各長度相加放入變量t o t中。
ls -l | awk '/^[^d]/ {print$9""t"$5} {tot+=$5}END{print "total KB:" tot}'
內置字符串函數
gsub 字符要用引號,數字不用
awk 'gsub(/12101/,"hello") {print $0} END{print FILENAME}' tab1
awk 'gsub(/12101/,3333) {print $0} END{print FILENAME}' tab1
index
awk '{print index($2,"D")""t";print $0}' tab1
awk '{print index($2,"D")""t" $0}' tab1
length
awk '{print length($2)""t" $0}' tab1
ma
awk '{print match($2,"M")""t" $0}' tab1
split
awk '{print split($2,new_array,"_")""t" $0}' tab1
sub 替換成功返回1,失敗返回0
awk '{print sub(/SYS/,"oracle",$2)""t" $0}' tab1
substr
awk '{print substr($2,1,3)""t" $0}' tab1
從s h e l l中向a w k傳入字符串
echo "Stand-by" | awk '{print length($0)""t"$0}'
8 Stand-by
file1="tab1"
cat $file1 | awk '{print sub(/ADMIN/,"sss",$2)""t"$0}'
字符串屏蔽序列
" b 退格鍵 " t t a b鍵
" f 走紙換頁 " d d d 八進制值
" n 新行 " c 任意其他特殊字符,例如" "為反斜線符號
" r 回車鍵
awk printf修飾符
- 左對齊
Wi d t h 域的步長,用表示步長
. p r e c 最大字符串長度,或小數點右邊的位數
如果用格式修飾輸出,要指明具體的域,程序不會自動去分辨
awk '{printf "%-2d %-10s %d"n", $1,$2,$3}' tab1
輸出結果
9 SYSADMIN 12101
9 SYSADMIN 12101
14 SYSADMIN 121010000012002
9 SYSADMIN 12101
2 JLNQ 12101
2 JLNQ 12101
7 SYSADMIN 12101
7 SYSADMIN 12101
6 ac_ds_e_rr_mr 13333
向一行a w k命令傳值
awk 'BEGIN{SYS="SYSADMIN"}{if($2==SYS) printf "%-2d %-10s %d"n", $1,$2,$3}' tab1
在動作后面傳入
awk '{if($2==SYS) printf "%-2d %-10s %d"n", $1,$2,$3}' SYS="SYSADMIN" tab1
awk腳本文件
SED用法
sed怎樣讀取數據
s e d從文件的一個文本行或從標准輸入的幾種格式中讀取數據,將之拷貝到一個編輯緩沖區,然后讀命令行或腳本的第一條命令,並使用這些命令查找模式或定位行號編輯它。重復此過程直到命令結束。
調用s e d有三種方式
使用s e d命令行格式為:
sed [選項] s e d命令 輸入文件。
記住在命令行使用s e d命令時,實際命令要加單引號。s e d也允許加雙引號。
使用s e d腳本文件,格式為:
sed [選項] -f sed腳本文件 輸入文件
要使用第一行具有s e d命令解釋器的s e d腳本文件,其格式為:
s e d腳本文件 [選項] 輸入文件
使用s e d在文件中定位文本的方式
x x為一行號,如1
x , y 表示行號范圍從x到y,如2,5表示從第2行到第5行
/ p a t t e r n / 查詢包含模式的行。例如/ d i s k /或/[a-z]/
/ p a t t e r n / p a t t e r n / 查詢包含兩個模式的行。例如/ d i s k / d i s k s /
p a t t e r n / , x 在給定行號上查詢包含模式的行。如/ r i b b o n / , 3
x , / p a t t e r n / 通過行號和模式查詢匹配行。3 , / v d u /
x , y ! 查詢不包含指定行號x和y的行。1 , 2 !
sed編輯命令
p 打印匹配行
= 顯示文件行號
a" 在定位行號后附加新文本信息
i" 在定位行號后插入新文本信息
d 刪除定位行
c" 用新文本替換定位文本
s 使用替換模式替換相應模式
r 從另一個文件中讀文本
w 寫文本到一個文件
q 第一個模式匹配完成后推出或立即推出
l 顯示與八進制A S C I I代碼等價的控制字符
{ } 在定位行執行的命令組
n 從另一個文件中讀文本下一行,並附加在下一行
g 將模式2粘貼到/pattern n/
y 傳送字符
n 延續到下一輸入行;允許跨行的模式匹配語句
sed編程舉例
打印單行 sed -n '2p' quo*
打印范圍 sed -n '1,3p' quote.txt
打印有此模式的行 sed -n '/disco/'p quote.txt
使用模式和行號進行查詢 sed -n '4,/The/'p quote.txt
sed -n '1,/The/'p quote.txt 會打印所有記錄?
用.*代表任意字符 sed -n '/.*ing/'p quote.txt
打印行號 sed -e '/music/'= quote.txt 或sed -e '/music/=' quote.txt
如果只打印行號及匹配行,必須使用兩個s e d命令,並使用e選項。
第一個命令打印模式
匹配行,第二個使用=選項打印行號,格式為sed -n -e /pattern/p -e /pattern/=。
sed -n -e '/music/p' -e '/music/'= quote.txt
先打印行號,再打印匹配行
sed -n -e '/music/=' -e '/music/'p quote.txt
替換
sed 's/The/Wow!/' quote.txt
保存到文件
sed '1,2 w filedt' quote.txt
讀取文件,在第一行后面讀取
sed '1 r sedex.txt' quote.txt
替換字符系列
如果變量x含有下列字符串:
x="Department+payroll%Building G"
要實現以下轉換:
+ to 'of'
% to located
語句: echo $x | sed 's/"+/ of /g' | sed 's/"%/ located /g'
————————————————————————————
shell命令執行的相應順序
&&
令1 && 命令2 如果這個命令1執行成功& &那么執行這個命2
mv myfile myfile2 && echo "if you are seeing this then mv was success!"
||
如果| |左邊的命令(命令1)未執行成功,那么就執行| |右邊的命令(命令2)
mv myfile myfile2 && echo "if you are seeing this then mv was success! "
從一個審計文件中抽取第1個和第2個域,並將其輸出到一個臨時文件中,如果這一操作未成功,我希望能夠收到一個相應郵件:
awk '{print$1,$2}' test3 >test2 || echo "sorry the extraction didn't work " | mail root
(命令1;命令2;. . .)
如果使用{ }來代替(),那么相應的命令將在子s h e l l而不是當前s h e l l中作為一個整體被執行,只有在{ }中所有命令的輸出作為一個整體被重定向時,其中的命令才被放到子s h e l l中執行,否則在當前s h e l l執行。
例子:
如果s o r t命令執行成功了,可以先將輸出文件備份,然后再打印
test.sorted && (cp test.sorted test.sorted_bak ;lp test.sorted)
經常使用的正則表達式舉例
^ 行首
$ 行尾
^ [ t h e ] 以t h e開頭行
[ S s ] i g n a [ l L ] 匹配單詞s i g n a l、s i g n a L、S i g n a l、S i g n a L
[Ss]igna[lL]". 同上,但加一句點
[ m a y M A Y ] 包含m a y大寫或小寫字母的行
^ U S E R $ 只包含U S E R的行
[tty]$ 以t t y結尾的行
" . 帶句點的行
^ d . . x . . x . . x 對用戶、用戶組及其他用戶組成員有可執行權限的目錄
^ [ ^ l ] 排除關聯目錄的目錄列表
^[^d] ls –l | grep ^[^d] 只顯示非文件夾的文件
[ . * 0 ] 0之前或之后加任意字符
[ 0 0 0 * ] 0 0 0或更多個
[ iI] 大寫或小寫I
[ i I ] [ n N ] 大寫或小寫i或n
[ ^ $ ] 空行
[ ^ . * $ ] 匹配行中任意字符串
^ . . . . . . $ 包括6個字符的行
[a- zA-Z] 任意單字符
[ a - z ] [ a - z ] * 至少一個小寫字母
[ ^ 0 - 9 " $ ] 非數字或美元標識
[ ^ 0 - 0 A - Z a - z ] 非數字或字母
[ 1 2 3 ] 1到3中一個數字
[ D d ] e v i c e 單詞d e v i c e或D e v i c e
D e . . c e 前兩個字母為D e,后跟兩個任意字符,最后為c e
" ^ q 以^ q開始行
^ . $ 僅有一個字符的行
^".[0-9][0-9] 以一個句點和兩個數字開始的行
' " D e v i c e " ' 單詞d e v i c e
D e [ V v ] i c e " . 單詞D e v i c e或d e v i c e
[ 0 - 9 ] " { 2 " } - [ 0 - 9 ] " { 2 " } - [ 0 - 9 ] " { 4 " } 對日期格式d d - m m - y y y y
[ 0 - 9 ] " { 3 " } " . [ 0 - 9 ] " { 3 " } " . [ 0 - 9 ] " { 3 " } " . [ 0 - 9 ] " { 3 " } I P地址格式
[ ^ . * $ ] 匹配任意行
[A-Za-z]* 匹配所有單詞
常用的g r e p選項
-c 只輸出匹配行的計數。
-i 不區分大小寫(只適用於單字符)。
-h 查詢多文件時不顯示文件名。
-l 查詢多文件時只輸出包含匹配字符的文件名。
-n 顯示匹配行及行號。
-s 不顯示不存在或無匹配文本的錯誤信息。
-v 顯示不包含匹配文本的所有行。
例子
grep -v "Sort" tab2 顯示不包含匹配文本的所有行
grep -n "Sort" tab2 顯示匹配行及行號
grep -c "Sort" tab2 只輸出匹配行的計數
精確匹配: grep "01">" tab2
grep -in "code" tab2 忽略大小寫
多次過濾
grep -in "code" tab2 | grep "02"
使用grep匹配“與”或者“或”模式
g r e p命令加- E參數,這一擴展允許使用擴展模式匹配。例如,要抽取城市代碼為2 1 9或2 1 6,方法如下:
grep –E ‘219|216’ tab2
g r e p允許使用國際字符模式匹配或匹配模式的類名形式。
類 等價的正則表達式
[ [ : u p p e r : ] ] [ A - Z ]
[ [ : a l n u m : ] ] [ 0 - 9 a - zA-Z]
[ [ : l o w e r : ] ] [ a - z ]
[ [ : s p a c e : ] ] 空格或t a b鍵
[ [ : d i g i t : ] ] [ 0 - 9 ]
[ [ : a l p h a : ] ] [ a - z A - Z ]
大多數系統管理員稱 / d e v / n u l l為比特池, 可以將之看成一個無底洞,有進沒有出,永遠也不會填滿。
要查看D N S服務器是否正在運行(通常稱為n a m e d),方法如下
ps -ef | grep "name"|grep -v "grep"
e g r e p
e g r e p接受所有的正則表達式,一個顯著特性是可以以一個文件作為保存的字符串,然后將之傳給e g r e p作為參數,為此使用- f開關。
egrep -f par2 tab2 par2是文件,里面包括各種匹配的具體格式
如果要查詢存儲代碼3 2 L或2 C C,可以使用(|)符號,意即“|”符號兩邊之一或全部。
egrep '(Code|Sort)' tab2
awk 內置函數詳細介紹
awk內置函數,主要分以下3種類似:算數函數、字符串函數、其它一般函數、時間函數
一、算術函數:
以下算術函數執行與 C 語言中名稱相同的子例程相同的操作:
| 函數名 | 說明 |
| atan2( y, x ) | 返回 y/x 的反正切。 |
| cos( x ) | 返回 x 的余弦;x 是弧度。 |
| sin( x ) | 返回 x 的正弦;x 是弧度。 |
| exp( x ) | 返回 x 冪函數。 |
| log( x ) | 返回 x 的自然對數。 |
| sqrt( x ) | 返回 x 平方根。 |
| int( x ) | 返回 x 的截斷至整數的值。 |
| rand( ) | 返回任意數字 n,其中 0 <= n < 1。 |
| srand( [Expr] ) | 將 rand 函數的種子值設置為 Expr 參數的值,或如果省略 Expr 參數則使用某天的時間。返回先前的種子值。 |
舉例說明:
[chengmo@centos5 ~]$ awk 'BEGIN{OFMT="%.3f";fs=sin(1);fe=exp(10);fl=log(10);fi=int(3.1415);print fs,fe,fl,fi;}'
0.841 22026.466 2.303 3
OFMT 設置輸出數據格式是保留3位小數
獲得隨機數:
[chengmo@centos5 ~]$ awk 'BEGIN{srand();fr=int(100*rand());print fr;}'
78
[chengmo@centos5 ~]$ awk 'BEGIN{srand();fr=int(100*rand());print fr;}'
31
[chengmo@centos5 ~]$ awk 'BEGIN{srand();fr=int(100*rand());print fr;}'41
二、字符串函數是:
| 函數 | 說明 |
| gsub( Ere, Repl, [ In ] ) | 除了正則表達式所有具體值被替代這點,它和 sub 函數完全一樣地執行,。 |
| sub( Ere, Repl, [ In ] ) | 用 Repl 參數指定的字符串替換 In 參數指定的字符串中的由 Ere 參數指定的擴展正則表達式的第一個具體值。sub 函數返回替換的數量。出現在 Repl 參數指定的字符串中的 &(和符號)由 In 參數指定的與 Ere 參數的指定的擴展正則表達式匹配的字符串替換。如果未指定 In 參數,缺省值是整個記錄($0 記錄變量)。 |
| index( String1, String2 ) | 在由 String1 參數指定的字符串(其中有出現 String2 指定的參數)中,返回位置,從 1 開始編號。如果 String2 參數不在 String1 參數中出現,則返回 0(零)。 |
| length [(String)] | 返回 String 參數指定的字符串的長度(字符形式)。如果未給出 String 參數,則返回整個記錄的長度($0 記錄變量)。 |
| blength [(String)] | 返回 String 參數指定的字符串的長度(以字節為單位)。如果未給出 String 參數,則返回整個記錄的長度($0 記錄變量)。 |
| substr( String, M, [ N ] ) | 返回具有 N 參數指定的字符數量子串。子串從 String 參數指定的字符串取得,其字符以 M 參數指定的位置開始。M 參數指定為將 String 參數中的第一個字符作為編號 1。如果未指定 N 參數,則子串的長度將是 M 參數指定的位置到 String 參數的末尾 的長度。 |
| match( String, Ere ) | 在 String 參數指定的字符串(Ere 參數指定的擴展正則表達式出現在其中)中返回位置(字符形式),從 1 開始編號,或如果 Ere 參數不出現,則返回 0(零)。RSTART 特殊變量設置為返回值。RLENGTH 特殊變量設置為匹配的字符串的長度,或如果未找到任何匹配,則設置為 -1(負一)。 |
| split( String, A, [Ere] ) | 將 String 參數指定的參數分割為數組元素 A[1], A[2], . . ., A[n],並返回 n 變量的值。此分隔可以通過 Ere 參數指定的擴展正則表達式進行,或用當前字段分隔符(FS 特殊變量)來進行(如果沒有給出 Ere 參數)。除非上下文指明特定的元素還應具有一個數字值,否則 A 數組中的元素用字符串值來創建。 |
| tolower( String ) | 返回 String 參數指定的字符串,字符串中每個大寫字符將更改為小寫。大寫和小寫的映射由當前語言環境的 LC_CTYPE 范疇定義。 |
| toupper( String ) | 返回 String 參數指定的字符串,字符串中每個小寫字符將更改為大寫。大寫和小寫的映射由當前語言環境的 LC_CTYPE 范疇定義。 |
| sprintf(Format, Expr, Expr, . . . ) | 根據 Format 參數指定的 printf 子例程格式字符串來格式化 Expr 參數指定的表達式並返回最后生成的字符串。 |
Ere都可以是正則表達式
gsub,sub使用
[chengmo@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}'
this is a test!test!
在 info中查找滿足正則表達式,/[0-9]+/ 用””替換,並且替換后的值,賦值給info 未給info值,默認是$0
查找字符串(index使用)
[wangsl@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'
ok未找到,返回0
正則表達式匹配查找(match使用)
[wangsl@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}'
ok
截取字符串(substr使用)
[wangsl@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'
s is a tes從第 4個 字符開始,截取10個長度字符串
字符串分割(split使用)
[chengmo@centos5 ~]$ awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}'
4
4 test
1 this
2 is
3 a
分割info,動態創建數組tA,這里比較有意思,awk for …in 循環,是一個無序的循環。 並不是從數組下標1…n ,因此使用時候需要注意。
格式化字符串輸出(sprintf使用)
格式化字符串格式:
其中格式化字符串包括兩部分內容: 一部分是正常字符, 這些字符將按原樣輸出; 另一部分是格式化規定字符, 以"%"開始, 后跟一個或幾個規定字符,用來確定輸出內容格式。
格式符 說明 %d 十進制有符號整數 %u 十進制無符號整數 %f 浮點數 %s 字符串 %c 單個字符 %p 指針的值 %e 指數形式的浮點數 %x %X 無符號以十六進制表示的整數 %o 無符號以八進制表示的整數 %g 自動選擇合適的表示法
[chengmo@centos5 ~]$ awk 'BEGIN{n1=124.113;n2=-1.224;n3=1.2345; printf("%.2f,%.2u,%.2g,%X,%o\n",n1,n2,n3,n1,n1);}'
124.11,18446744073709551615,1.2,7C,174
三、一般函數是:
| 函數 | 說明 |
| close( Expression ) | 用同一個帶字符串值的 Expression 參數來關閉由 print 或 printf 語句打開的或調用 getline 函數打開的文件或管道。如果文件或管道成功關閉,則返回 0;其它情況下返回非零值。如果打算寫一個文件,並稍后在同一個程序中讀取文件,則 close 語句是必需的。 |
| system(Command ) | 執行 Command 參數指定的命令,並返回退出狀態。等同於 system 子例程。 |
| Expression | getline [ Variable ] | 從來自 Expression 參數指定的命令的輸出中通過管道傳送的流中讀取一個輸入記錄,並將該記錄的值指定給 Variable 參數指定的變量。如果當前未打開將 Expression 參數的值作為其命令名稱的流,則創建流。創建的流等同於調用 popen 子例程,此時 Command 參數取 Expression 參數的值且 Mode 參數設置為一個是 r 的值。只要流保留打開且 Expression 參數求得同一個字符串,則對 getline 函數的每次后續調用讀取另一個記錄。如果未指定 Variable 參數,則 $0 記錄變量和 NF 特殊變量設置為從流讀取的記錄。 |
| getline [ Variable ] < Expression | 從 Expression 參數指定的文件讀取輸入的下一個記錄,並將 Variable 參數指定的變量設置為該記錄的值。只要流保留打開且 Expression 參數對同一個字符串求值,則對 getline 函數的每次后續調用讀取另一個記錄。如果未指定 Variable 參數,則 $0 記錄變量和 NF 特殊變量設置為從流讀取的記錄。 |
| getline [ Variable ] | 將 Variable 參數指定的變量設置為從當前輸入文件讀取的下一個輸入記錄。如果未指定 Variable 參數,則 $0 記錄變量設置為該記錄的值,還將設置 NF、NR 和 FNR 特殊變量。 |
打開外部文件(close用法)
[chengmo@centos5 ~]$ awk 'BEGIN{while("cat /etc/passwd"|getline){print $0;};close("/etc/passwd");}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
逐行讀取外部文件(getline使用方法)
[chengmo@centos5 ~]$ awk 'BEGIN{while(getline < "/etc/passwd"){print $0;};close("/etc/passwd");}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[chengmo@centos5 ~]$ awk 'BEGIN{print "Enter your name:";getline name;print name;}'
Enter your name:
chengmo
chengmo
調用外部應用程序(system使用方法)
[chengmo@centos5 ~]$ awk 'BEGIN{b=system("ls -al");print b;}'
total 42092
drwxr-xr-x 14 chengmo chengmo 4096 09-30 17:47 .
drwxr-xr-x 95 root root 4096 10-08 14:01 ..
b返回值,是執行結果。
四、時間函數
| 函數名 | 說明 |
| mktime( YYYY MM DD HH MM SS[ DST]) | 生成時間格式 |
| strftime([format [, timestamp]]) | 格式化時間輸出,將時間戳轉為時間字符串 具體格式,見下表. |
| systime() | 得到時間戳,返回從1970年1月1日開始到當前時間(不計閏年)的整秒數 |
創建指定時間(mktime使用)
[chengmo@centos5 ~]$ awk 'BEGIN{tstamp=mktime("2001 01 01 12 12 12");print strftime("%c",tstamp);}'
2001年01月01日 星期一 12時12分12秒
[chengmo@centos5 ~]$ awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=mktime("2001 02 01 0 0 0");print tstamp2-tstamp1;}'
2634468求2個時間段中間時間差,介紹了strftime使用方法
[chengmo@centos5 ~]$ awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=systime();print tstamp2-tstamp1;}'
308201392
strftime日期和時間格式說明符
格式 描述 %a 星期幾的縮寫(Sun) %A 星期幾的完整寫法(Sunday) %b 月名的縮寫(Oct) %B 月名的完整寫法(October) %c 本地日期和時間 %d 十進制日期 %D 日期 08/20/99 %e 日期,如果只有一位會補上一個空格 %H 用十進制表示24小時格式的小時 %I 用十進制表示12小時格式的小時 %j 從1月1日起一年中的第幾天 %m 十進制表示的月份 %M 十進制表示的分鍾 %p 12小時表示法(AM/PM) %S 十進制表示的秒 %U 十進制表示的一年中的第幾個星期(星期天作為一個星期的開始) %w 十進制表示的星期幾(星期天是0) %W 十進制表示的一年中的第幾個星期(星期一作為一個星期的開始) %x 重新設置本地日期(08/20/99) %X 重新設置本地時間(12:00:00) %y 兩位數字表示的年(99) %Y 當前月份 %Z 時區(PDT) %% 百分號(%)
以上是awk常見 內置函數使用及說明,希望對大家有所幫助。
正則的基本語法
一、基本語法
正則的基本語法就大概是下面這些,但是正則遠不止這些,甚至可以寫一本書,當然了,我們這里只列舉一些簡單的
用法,這些已經可以解決大部分實際問題了。
1、字符類
| 字符 | 含義 | 舉例 |
|---|---|---|
| . | 匹配任意一個字符 | abc. 可 以匹配abcd 、abc9 等 |
| [] | 匹配括號中的任意一個字符 | [abc]d 可以匹配ad 、bd 或cd |
| - | 用在[]中,表示字符范圍 | [0-9a-fA-F] 可以匹配一位十六進制數字 |
| ^ | 如果位於[]的開頭,則匹配除去括號中字符之外的一切字符 | [^xy] 匹配除xy 之外的任一字符,因此[^xy]1 可以 匹配a1、b1 但不匹配x1 、y1 |
| [[:xxx:]] | grep 工 具預定義的一些命名字符類 | [[:alpha:]] 匹配一個字母,[[:digit:]] 匹配一個數字 |
2、數量限定符
| 字符 | 含義 | 舉例 |
|---|---|---|
| ? | 緊跟在它前面的單元匹配零次或一次 | [0-9]?/.[0-9] 匹配0.0 、2.3 、.5 等,由於. 在正則表達式中是一個特殊字符,所以需要用/ 轉 義一下,取字面值 |
| + | 緊跟在它前面的單元匹配一次或多次 | [a-zA-Z0-9.-_]+@[a-zA-Z0-9.-_]+/.[a-zA-Z0-9.-_]匹配email |
| * | 緊跟在它前面的單元匹配零次或多次 | [0-9][0-9]* 匹配至少一位數字,等價於[0-9]+ ,[a-zA-Z_]+[a-zA-Z_0-9]* 匹 配C語言的標識符 |
| {N} | 緊跟在它前 面的單元應精確匹配N次 | [1-9][0-9]{2} 匹 配從100 到999 的整數 |
| {N,} | 緊跟在它前面的單元至少要匹配n次 | [1-9][0-9]{2,} 匹配三位以上(含三位)的整數 |
| {,M} | 緊跟在它前面的單元至多匹配m次 | [0-9]{,1}和[0-9]?意義一樣, |
| {N,M} | 緊跟在它前面的單元至少匹配n次,至多匹配m次 | [0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.用於匹配ip地址 |
3、位置限定符
| 字符 | 含義 | 舉例 |
|---|---|---|
| ^ | 匹配行首的位置 | ^content匹配以content開頭的行 |
| $ | 匹配行末的位置 | :$匹配以:結尾的行,^$匹配空行 |
| /< | 匹配單詞開頭的位 置 | /<th 匹配... this ,但不匹配ethernet 、tenth |
| /> | 匹 配單詞結尾的位置 | p/> 匹配leap ... ,但不匹配parent 、sleepy |
| /b | 匹 配單詞開頭或結尾的位置 | ap/b匹配leap,/ble匹配leap,/bat/b 匹配... at ... ,但不匹配cat、atexit 、batch |
| /B | 匹配非單詞開頭和結尾的位置 | /Bat/B 匹配battery ,但不匹配... attend 、hat ... |
4、其他特殊字符
| 字符 | 含義 | 舉例 |
|---|---|---|
| / | 轉義字符,普通字符轉義為特殊字符,特殊字符轉義為普通字符 | 普 通字符< 寫成/< 表 示單詞開頭的位置,特殊字符. 寫成/.以 及/ 寫成// 就當作普通字符來 匹配 |
| () | 將正則表達式的一部分括起 來組成一個單元,可以對整個單元使用數量限定符 | ([0-9]{1,3}/.){3}[0-9]{1,3} 匹 配IP地址 |
| | | 連接兩個表達式,表示或的關系 | n[o-either]可以匹配no或neither |
- [root@linux ~]# sed [-nefr] [動作]
- 參數∶
- -n ∶使用安靜(silent)模式。在一般 sed 的用法中,所有來自 STDIN
- 的資料一般都會被列出到螢幕上。但如果加上 -n 參數后,則只有經過
- sed 特殊處理的那一行(或者動作)才會被列出來。
- -e ∶直接在指令列模式上進行 sed 的動作編輯;
- -f ∶直接將 sed 的動作寫在一個檔案內, -f filename 則可以執行 filename 內的
- sed 動作;
- -r ∶sed 的動作支援的是延伸型正規表示法的語法。(預設是基礎正規表示法語法)
- -i ∶直接修改讀取的檔案內容,而不是由螢幕輸出。
- 動作說明∶ [n1[,n2]]function
- n1, n2 ∶不見得會存在,一般代表『選擇進行動作的行數』,舉例來說,如果我的動作
- 是需要在 10 到 20 行之間進行的,則『 10,20[動作行為] 』
- function 有底下這些咚咚∶
- a ∶新增, a 的后面可以接字串,而這些字串會在新的一行出現(目前的下一行)~
- c ∶取代, c 的后面可以接字串,這些字串可以取代 n1,n2 之間的行!
- d ∶刪除,因為是刪除啊,所以 d 后面通常不接任何咚咚;
- i ∶插入, i 的后面可以接字串,而這些字串會在新的一行出現(目前的上一行);
- p ∶列印,亦即將某個選擇的資料印出。通常 p 會與參數 sed -n 一起運作~
- s ∶取代,可以直接進行取代的工作哩!通常這個 s 的動作可以搭配
- 正規表示法!例如 1,20s/old/new/g 就是啦!
- 范例∶
- 范例一∶將 /etc/passwd 的內容列出,並且我需要列印行號,同時,請將第 2~5 行刪除!
- [root@linux ~]# nl /etc/passwd | sed '2,5d'
- 1 root:x:0:0:root:/root:/bin/bash
- 6 sync:x:5:0:sync:/sbin:/bin/sync
- 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
- .....(后面省略).....
- # 看到了吧?因為 2-5 行給他刪除了,所以顯示的資料中,就沒有 2-5 行棉~
- # 另外,注意一下,原本應該是要下達 sed -e 才對,沒有 -e 也行啦!
- # 同時也要注意的是, sed 后面接的動作,請務必以 '' 兩個單引號括住喔!
- # 而,如果只要刪除第 2 行,可以使用 nl /etc/passwd | sed '2d' 來達成,
- # 至於第 3 到最后一行,則是 nl /etc/passwd | sed '3,$d' 的啦!
- 范例二∶承上題,在第二行后(亦即是加在第三行)加上『drink tea?』字樣!
- [root@linux ~]# nl /etc/passwd | sed '2a drink tea'<
bash shell - sed, awk文本捕獲及替換
bash shell雖然支持正則表達式, 但是正則操作卻不大給力.看以下示例
case需求.
stream='background-image: url (a.jpg)asdfasdfasdf ;background:url(b.jpg);background'
需要將背景圖片內容a.jpg及b.jpg后追加一個簽名串.
sed替換不給力
如果用sed, 替換是不會有問題, 但是要在一句代碼里進行捕獲多個圖, 將進行替換, 查閱了相關的sed文檔, 貌似是需求處理不了.
代碼示例
echo $stream | sed 's#.*url *( *\(.*\) *).*#\1#'
#輸出b.jpg
awk代碼塊
用awk的話,(g)sub又沒有sed里的匹配后的"后向引用"(即"\1"). 但是可以有代碼塊可操作.
原理可利用awk里的函數match先用正則匹配url()里的內容, 再用substr將內容取出, 隨之將流的位置置后.
循環操作.
代碼如下:
matches=$(echo $stream | awk 'BEGIN {ORS=" "} END {
gsub(/ */,"", $0)
input=$0
while (match(input, "url([^?;)]+)")) {
print substr(input, RSTART+4, RLENGTH-4)
input=substr(input, RSTART+RLENGTH)
}
}')
for bg_file in `echo "${matches}"`; do
md5_code="test"
stream=$(echo "${stream}" | sed "s#url *( *${bg_file} *)#url(${bg_file}?v=${md5_code})#")
done
echo "${stream}"
總結
從以上的示例可以看出, awk幾乎可以替代sed, 但是對於固定替換, sed使用起來更方便.
sed從使用理解上看, 與vi的命令操作很相似.
而在awk里塊里幾乎可以操作任意文本流.
另外要說明的是, 這兩個命令所支持的正則都像是標准perl里的子集, 沒有貪婪匹配與非貪婪匹配之分.
Linux shell編程之awk的用法
1. awk的使用
基本功能:在文件或字符串中基於指定規則瀏覽和抽取信息。awk抽取信息後,才能進行其他文本操作。完整的awk腳本通常用來格式化文本文件信息。
調用方式:
1. 命令行方式
2. 將所有awk命令插入一個文件,並使awk程序可執行,然后使awk命令解釋器作為腳本的首行,以便通過鍵入腳本名稱來調用它。
3. 將所有的awk命令插入一個單獨文件,然后調用。
選項說明:-F 域符號 缺省為空格
-f 指明awk腳本
2. 模式和動作
1. 任何awk語句都由模式和動作組成。在一個awk腳本中可能有許多語句。
模式部分決定動作語句何時觸發及觸發事件。模式缺省為執行狀態。
處理即對數據進行的操作。
2. 模式可以是任何條件語句或復合語句或正則表達式。
3. 模式包括兩個特殊字段BEGIN和END。
域和記錄
域標識:$1,$2,…,$n。用逗號做域分隔。$0表示所有域。
打印域或所有域:print命令
注:當碰到awk錯誤時,可相應查找:
1. 確保整個awk命令用單引號括起來
2. 確保命令內所有引號成對出項
3. 確保用花括號括起動作語句,用圓括號括起條件語句
4. 不要忘記使用花括號
條件操作符
~ 匹配正則表達式
!~ 不匹配正則表達式
內置變量:
NF:每一條記錄中域名數
是將變量$PWD的返回值傳入awk並顯示其目錄。
可以利用NF獲取文件名
注:但這里指定域分隔符為/
NR:記錄個數
Linux shell編程之sed用法
1. 是一個非交互性文本流編輯器。它編輯文件或標准輸入導出的文本拷貝。
2. 通過行號或正則表達式指定要改變的文本行
3. sed不與初始文件打交道,而只與它的一個拷貝打交道,如果操作結果沒有重定向到一個文件,那么將輸出到屏幕。
調用方式:
a. 命令行方式
b. 將sed命令插入腳本文件中,然后調用sed
c. 將sed命令插入腳本文件中,使得腳本文件為可執行。
保存sed輸出
重定向到一個新文件 >
sed中定位文本的方式
x 一行號
x,y 行號范圍
/pattern/ 查詢包含模式的行
/pattern/pattern/ 查詢包含兩個模式的行
/pattern/,x 在指定行號上查詢匹配模式的行
x,/pattern/ 通過行號和模式查詢匹配行
x,y! 查詢不包含行號x,y的行
sed編輯命令
p 打印文本
匹配元字符$前,必須使用反斜線\
= 打印行號 使用-e選項
如果既打印行號又打印匹配行,必須使用兩個sed命令,並使用-e選項
附加文本
使用符號a\ ,可以指定文本一行或多行附加到指定行。若不指定文本放置位置位置,sed缺省放置在每一行后面。
創建sed腳本文件
創建腳本文件,第一行為:
#!/bin/sed -f ----注 說明sed命令解釋行。腳本在這一行查找sed以運行命令,這里定位在/bin
插入文本:在指定行前面插入,它也只接受一個地址。
刪除文本:d
替換命令用替換模式替換指定模式
使用sed實現的一個重要功能是在另一個系統中下載的文件中剔除控制字符。
1. 使用s/-*//g刪除橫線-----
2. 使用/^$s/d刪除空行
3. 使用$d刪除最后一行
4. 使用1d刪除第一行
5. 使用awk{print $1}打印第一列
