awk推薦去看朱雙印的博客「awk從放棄到入門」,寫的真的很好,本文的awk就總結於它。html
awk實際上是一門編程語音,它支持條件判斷、數組、循環等功能。因此,咱們也能夠把awk理解成一個腳本語言解釋器node
awk 【option】 ‘program’ file1,file2linux
1) BEGIN和END模塊只能有一個。中間的pattern匹配,能夠有多個git
NR==2{print $1}NR==5{print $1}正則表達式
2) BEGIN模塊,表明awk在處理文本前要作的事。即便不接收文件名,僅僅使用BEGIN模塊打印,也能正常輸出shell
awk ‘BEGIN {print 「111」,」222」}’編程
3) END模塊,表明awk在處理文本後要作的事數組
awk ‘{print $1,$2} END{print ‘333’,’444’}’test緩存
變量名編輯器 |
屬性 |
備註 |
$0 |
當前記錄。即一整行 |
|
$1~$n |
當前記錄的第n個字段 |
awk ‘{print 「str:」$1}’ |
FS |
輸入字段分隔符,默認space |
awk –F ‘:’ awk –v FS=’:’ |
RS |
輸入記錄分隔符,默認爲\n |
若是RS=」」,會以空白行分隔 |
OFS |
輸出字段分隔符,默認space |
|
ORS |
輸出的記錄分隔符,默認\n |
|
NF |
當前記錄中的字段個數,即多少列 |
|
NR |
行號,從1開始 |
|
FNR |
各文件分別顯示行號 |
|
FILENAME |
當前文件名 |
awk ‘{print FILENAME,$0}’ |
ARGC |
命令行參數的個數 |
|
ARGV |
數組,保存的是命令行所給定的參數 |
ARGV[0]是awk,單引號中的不算參數,處理的文件是參數 |
awk除了使用內置變量,還能夠本身定義變量。
方法一:-v varname=value 變量名區分字符大小寫。-v:設置變量
方法二:在program中定義
1、-v 定義
2、在program定義
awk自己負責文本切割,printf動做則負責格式格式化文本。在瞭解awk的printf動做前,須要首先了解printf命令
在shell中,echo和printf都是輸出文本的命令。echo輸出的字符串,會自動在末尾加上\n,
而printf不會。printf的做用是按照咱們指定的格式輸出文本,因此\n,也須要咱們本身指定
注意看3,printf的優點就在於,能夠用格式替換符,幫咱們處理一長串的str
名稱 |
含義 |
%s |
字符串 |
%f |
浮點格式 |
%b |
對應的參數包含轉義字符時,對應的轉義字符會被轉義 |
%c |
ASCII字符,顯示對應參數的第一個字符 |
%d,%i |
十進制整數 |
%o |
不帶正負號的八進制值 |
%u |
不帶正負號的十進制值 |
%x |
不帶正負號的十六進制值,用a到f表示10至15 |
%X |
不帶正負號的十六進制值,用A到F表示10至15 |
%% |
表示‘%’自己 |
名稱 |
含義 |
\a |
警告字符,常爲ASCII的BEL字符 |
\b |
後退 |
\c |
不顯示輸出結果中任何結尾的換行字符(%b格式下的參數字符串依然有效) |
\f |
換頁(formfeed) |
\n |
換行 |
\r |
回車 |
\t |
水平製表符 |
\v |
垂直製表符 |
\\ |
「\」自己 |
\ddd |
表示1到3位數八進制值得字符串,僅在字符格式串中有效 |
\0ddd |
表示1到3位數八進制值得字符串 |
參數 |
含義 |
%7s |
7就表明當前替換符對應的輸出長度爲7個字符寬,不足補齊,超出也正常顯示 |
%-7s |
「-」,表示左對齊,不加時,是右對齊 |
%+5d |
正數會自動變爲+num |
%12.3f |
「.3」表示保留小數點後三位,%f默認是小數點後6位 |
%12.5d |
「.5」表示整數的長度,不足用0補齊 |
awk的printf動做與shell的printf命令很像,只是要注意幾點:
1) 使用printf動做輸出的文本不會換行,要本身手動加\n
2) 使用printf動做時,「指定的格式」與「被格式化的文本」間,要用「逗號」隔開
3) 使用printf動做,「格式替換符」與「被格式化的文本」數量一一對應
例子
awk -v FS=':' 'BEGIN{printf "%-10s\t %s\n","用戶名稱","用戶ID"} {printf "%-10s\t %s\n",$1,$3}' /etc/passwd
用戶名稱 用戶ID
root 0
bin 1
grep ‘^root’/etc/passwd
awk ‘/^root/{print $0}’ /etc/passwd
1)awk命令中的正則是「擴展正則表達式」
2)當使用{x,y}或[[:space]],這種正則時,要加上參數—posix
3)注意對「\」和「.」轉義
兩個正則的就是行範圍模式,從正則1匹配的行開始,到正則2匹配的行結束
正則匹配符
~ |
匹配後面的正則。’$1~/pattern/’ |
!~ |
不匹配後面的正則’$1!~/pattern/’ |
上圖的動做分爲兩個部分:
1) 紅線標註:最外側的括號「{}」。「組合語句」類型的動做,將多個代碼組合成代碼塊
2) 藍線標註:「print $0」。print是「輸出語句」類型的動做
例子
若是if對應的{},只有一條命令,能夠省略{}
do…while循環不管是否知足while的條件,都會先執行一次do裏的命令
# 打印一遍test
# 打印5遍test
# 1~5,不打印3
# 打印1~3
awk中,exit表示跳事後序全部動做,直接執行END內的命令。若是沒有END模式,則會直接結束awk命令
# 只打印1
# 不會打印$0
next的做用是跳過當前行。直接從下一行 開始處理
# 跳過第2行
1)awk中的數組是一個使用字符串做爲下標的「關聯數組」。
2)咱們在使用時,能夠用 數字/字符串 做爲下標,不過使用數字做爲下標時,awk默認會把「數字」下標轉換爲「字符串」。
3)在awk中,元素的值能夠設置爲「空」。
4)當一個元素不存在於數組時,若是咱們直接引用這個不存在的元素,awk會自動建立這個元素,而且默認爲這個元素賦值爲「空字符串」
5)在awk中,判斷數組中元素是否存在,用「if(下標 in 數組名)」。即判斷數組中是否有key
6)使用split函數生成的數組,下標默認是從1開始的
# 建立數組,直接建立就能夠
# 刪除數組中的元素
awk ‘BEGIN{ …;delete huluwa[0]}’
# 刪除整個數組
awk ‘BEGIN{ …;delete huluwa}’
# for循環有序遍歷數組。只有下標是數字時,經過下標的遞增,纔能有序遍歷
awk ‘BEGIN{ …;for (i=1;i<=3;i++){print i,huluwa[i];} }’
# for循環無序遍歷數組。由於awk數組自己是無序的關聯數組
awk ‘BEGIN{ …;for (i in huluwa){print i,huluwa[i]} }’
# 實例應用——統計某文件$1 重複出現的次數
awk ‘{count[$1]++} END{ for (i in count ) {print i,count[i]} }’ file
# 實例應用——統計某文本人名出現次數
awk ‘{ for (i=1;i<=NF;i++) {count[$i]++} } END{ for (a in count) {print a,count[a]} }’
rand函數固定打印了0.237788,srand函數固定打印1,二者合用,可生成小於1的隨機數
# rand函數
awk 'BEGIN{print rand()}'
0.237788
# srand函數
awk 'BEGIN{print srand()}'
1
# 生成小於1的隨機數
awk 'BEGIN{srand();print rand()}'
0.319498
# 經過隨機數乘100,在經過int函數取整,生成0~100間的隨機數
awk 'BEGIN{srand();print int(100*rand())}'
76
這兩個函數用於替換某些 文本
awk ‘{ gsub (「old」,「new」,$1);print $0}’file
awk ‘{ gsub (「[a-z]」,「new」,$1);print $0}’file
gsub將指定範圍內匹配的字符所有替換爲新字符
sub用法與gsub同樣,但只替換匹配範圍內第一次匹配到的字符
# 好比某文件就一行,$1=aaa。
gsub(「a」,「b」),則$1=bbb。第三個參數不加,則默認爲$0
sub(「a」,「b」),則$1=baa。
length函數可獲取指定字符串的長度。不指定參數,默認爲$0
awk ‘{ for (i=1;i<=NF;i++) {print $i,length($i)} }’file
獲取指定字符串位於整個字符串中的位置
awk ‘{print index($0,「LEE」)}’file
0
7
0
index函數在每一行中查找LEE,若是該行沒有,返回0,該行有,返回位置
split函數能夠切割字符串,幫咱們動態生成數組。生成的數組下標從1開始
# 將ts以「;」分隔,並將分隔後的str保存到huluwa數組中
awk –v ts=」one;two;three」‘BEGIN{ print split(ts,huluwa,」;」)}’
# split函數的返回值就是數組長度
split(ts,huluwa,」;」) == 3
asort函數根據數組的value值進行排序
# asort排序後,原有key將被數字替代
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t) ; for (i in t){print i,t[i]} }'
1 35
2 66
3 88
# asort排序時,新建一個數組。t[]不變,新創了new[]
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t,new) ; \
for (i in new){print i,new[i]} }'
# asort函數的返回值就是數組的長度
asort(t,new)==3
asorti函數會對原數組的key排序,而後將key做爲value生成一個新數組
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);for (i in new){print i,new[i]} }'
1 a
2 b
3 c
# 經過asorti排列原數組
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);\
for (i in new){print i,new[i],t[new[i]] } }'
1 a 66
2 b 88
3 c 35
# if…else判斷用戶類型
awk –F : ‘{ if($3<500){usertype=「系統用戶」}else{ usertype=「普通用戶」};\
print $1,usertype }’/etc/passwd
# 三元運算符替換if…else
awk –F : ‘{ usertype=$3<500?「系統用戶」: 「普通用戶」;\
print $1,usertype }’/etc/passwd
l $3<500:條件判斷
l ?」系統用戶」:爲真,則「系統用戶」賦給usertype
l :「普通用戶」:爲假,則「普通用戶」賦給usertype
# 三元運算符統計「系統用戶」和「普通用戶」數量
awk -F: '{$3<500?a++:b++}END{print a,b}' /etc/passwd
# 打印奇數行
awk ‘a=!a’flie
# 打印偶數行
awk ‘!(a=!a)’flie
解析:
咱們知道awk的正則匹配是
/
但若是咱們不加print動做,僅僅有正則,那麼會默認打印$0。
awk ‘/正則/’file
而在awk中,非0/非空str表示「真」。0/空表示「假」
# 注意,這不是正則,‘2’不爲0/空,打印file全部
awk '2' file
因此’a=!a’
1) a沒有定義,初始化a=‘’,a爲「假」
2) !a爲「真」
3) a=!a,a變爲「真」,打印第1行
4) !a又變爲「假」,不打印第2行
‘!(a=!a)’
1)a=!a爲真,!(a=!a)爲假,不打印 第1行
2)a=!a爲假,!(a=!a)爲真,打印第2行
awk從放棄到入門 (http://www.zsythink.net/?s=awk)
awk用法(使用入門) (http://www.javashuo.com/article/p-yqjjrswt-da.html)
官方文檔 (https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents)
sed命令是一個面向字符流的非交互式編輯器,按行來處理文本內容。在shell中,使用sed來批量修改文本內容是很是方便的。
sed 把每一行都存在臨時緩存區中,對這個副本進行編輯,因此不會修改或破壞源文件。具體過程以下:
1)sed 把當前正在處理的行保存在一個臨時緩存區中,這個緩存區稱爲「模式空間」或「臨時緩衝」。
2)sed 對模式空間中的行後處理完畢後,就把該行發送到屏幕上(除非以前有命令刪除這一行或取消打印操做)。
3)sed處理完輸入文件的最後一行後, sed 便結束運行。
sed的命令格式
sed [option] 'sed command'filename
sed的腳本格式
sed [option] -f 'sed script'filename
-n :使用安靜(silent)模式。在通常 sed 的用法中,全部來自 STDIN 的數據通常都會被列出到終端上。但若是加上 -n 參數後,則只有通過sed 特殊處理的那一行(或者動做)纔會被列出來。
-e :多重編輯,且命令順序會影響結果
-f :直接將 sed 的動做寫在一個文件內, -f filename 則能夠運行 filename 內的 sed 動做;
-r :sed 的動做支持的是延伸型正規表示法的語法。(默認是基礎正規表示法語法)
-i :直接修改讀取的文件內容,而不是輸出到終端。
x |
x爲行號 |
x,y |
表示行號從x到y |
/pattern |
查詢包含模式的行 |
/pattern /pattern |
查詢包含兩個模式的行 |
pattern/,x |
在給定行號上查詢包含模式的行 |
x,/pattern/ |
經過行號和模式查詢匹配的行 |
x,y! |
查詢不包含指定行號x和y的行 |
命 令 |
說 明 |
a\ |
在當前行後添加一行或多行。 sed ‘/pattern/a new_str’file;sed ‘1a new_str‘ file |
c\ |
用新文本修改(替換)當前行中的文本 |
d |
刪除行 |
i\ |
在當前行以前插入文本 |
h |
把模式空間裏的內容複製到暫存緩存區 |
H |
把模式空間裏的內容追加到暫存緩存區 |
g |
取出暫存緩衝區裏的內容,將其複製到模式空間,覆蓋該處原有內容 |
G |
取出暫存緩衝區裏的內容,將其複製到模式空間,追加在原有內容後面 |
l |
列出非打印字符 |
p |
打印匹配行(和-n選項一塊兒合用) |
= |
顯示文件行號 |
{} |
定位執行的命令組,「;」隔開 |
n |
讀入下一輸入行,並從下一條命令而不是第一條命令開始處理 |
q |
結束或退出 sed |
r filename |
從另外一個文件中讀文本,相似輸入重定向 < |
! |
對所選行意外的全部行應用命令 |
s |
用一個字符串替換另外一個 |
g |
在行內進行全局替換 |
p |
打印行 |
w filename |
寫文本到一個文件,相似輸出重定向 > |
x |
交換暫存緩衝區與模式空間的內容 |
y |
傳送字符,替換單個字符(不能對正則表達式使用 y 命令) |
元字符 |
功 能 |
示 例 |
示例的匹配對象 |
^ |
行首定位符 |
/^love/ |
匹配全部以 love 開頭的行 |
$ |
行尾定位符 |
/love$/ |
匹配全部以 love 結尾的行 |
. |
匹配除換行外的單 |
/l..e/ |
匹配包含字符 l、後跟兩個任意 |
* |
匹配零個或多個前 |
/*love/ |
匹配在零個或多個空格緊跟着 |
[] |
匹配指定字符組內 |
/[Ll]ove/ |
匹配包含 love 和 Love 的行 |
[^] |
匹配不在指定字符 |
/[^A-KM-Z]ove/ |
匹配包含 ove,但 ove 以前的那 |
\(..\) |
保存已匹配的字符 |
||
& |
保存查找串以便在 |
s/love/**&**/ |
符號&表明查找串。字符串 love |
\< |
詞首定位符 |
/\<love/ |
匹配包含以 love 開頭的單詞的 |
\> |
詞尾定位符 |
/love\>/ |
匹配包含以 love 結尾的單詞的 |
x\{m\} |
連續 m 個 x |
/o\{5\}/ |
分別匹配出現連續 5 個字母 o、 |
x\{m,\} |
至少 m 個 x |
/o\{5,\}/ |
|
x\{m,n\} |
至少 m 個 x,但不 |
/o\{5,10\}/ |
[:digit:] |
全部數字,即[0-9] |
[:lower:] |
全部的小寫字母 |
[:upper:] |
全部的大寫字母 |
[:alpha:] |
全部的字母 |
[:alnum:] |
至關於0-9a-zA-Z |
[:space:] |
空白字符 |
[:punct:] |
全部標點符號 |
sed -n '1,4{=;p}' passwd
sed ‘/pattern/a new_str’file # 在匹配模式的下一行新,增str
sed ‘1a new_str‘ file # 在第1行後,新增str
# 過濾#註釋行和空格行
sed –n ‘/^#/!{/^$/!p}’file
l /^#/!:打印除了#開頭的行
l {/^$/!p}:打印除了空格行
# 刪除#註釋行和空行。有時-e的不一樣順序,會形成不一樣結果。好比 -e ’1a’–e ‘2a’
sed –e ‘/^#/d’-e ‘/^$/d’ file
# 將hello所在行的END替換爲tail
sed –i ‘/hello/s@END@tail@#’
l @:地址定界符,還能夠是/,#等其餘特殊字符
# 將目錄下的.txt文件批量命名爲.sh文件
find . –name ‘*.txt’ | sed –re ‘s#(.*).txt#mv & \1.sh#e’
l (.*).txt:查找的文件,對應&
l (.*):分組,對應\1,多個括號就依次對應\2,\3,…
l e:執行mv命令
# 刪除文件中含有you這個單詞的行。\必須加
sed ‘/\<you\>/d’file
linux sed命令詳解(推薦) (http://www.jb51.net/article/111306.htm)
linux命令總結sed命令詳解 (https://www.cnblogs.com/ginvip/p/6376049.html)
sed命令詳解 (http://www.javashuo.com/article/p-knxuhypx-co.html)
grep適合單純的查找或匹配文本。
--color=atuo或者—color:對匹配到的文本着色
-i:忽略大小寫
-n:顯示結果所在行號
-c:統計匹配到的行數。注意:是匹配到的總行數,不是匹配到的次數
-o:只顯示符合條件的字符串,可是不整行顯示。每一個符合條件的字符串單獨顯示一行
-v:接啥排除啥
-w:匹配整個單詞,若是是字符創中包含這個單詞,則不會匹配
-Ax:輸出的時候包含結果所在行以後的指定行數,x是行數,A:after。若是有多個匹配結果。則每一個結果的後x行都會顯示
-Bx:輸出的時候包含結果所在行以前的指定行數,x是行數,B:before。
-Cx:輸出的時候包含結果所在行以前和行以後的指定行數,x是行數,C:context
-e:實現多個選項的匹配,邏輯or關係
-q:靜默模式,不輸出任何信息。於「echo $?」合用,查看是否匹配到,0表示匹配到,1表示沒有匹配到
-P:使用兼容的perl的正則
-E:使用擴展正則表達式,同egrep
# -e的使用
grep –e’one’ –e’two’ file # 能夠同時匹配one和two
sed -nr 's#[:/0-9]+# #gp' passwd.txt #對passwd.txt文件進行處理,將 FS 變爲空格
sed -nr 's#[:/0-9]+# #gp' passwd.txt | sed -nr 's# #\n#gp' | sort | uniq -c | sort –nr
l sed -nr 's#[:/0-9]+# #gp' passwd.txt #對passwd.txt文件進行處理,將 FS 變爲空格
awk 'BEGIN{RS="[:/0-9]+"}{print $0}' passwd.txt | head -n -1 | sort | uniq -c | sort -nr # head -n -1 是由於最後一行是空行,須要排除
# awk使用{m,n},須要加--posix
awk --posix ‘$1~/o{1,2}/{print NR,$1}’passwd
sed -nr 's#^$##gp' file | wc -l
grep "^$" file |wc -l
awk '/^$/{a=a+1} END{print a}' file
awk -F: '{$3>5?a++:b++} END{print a}' /etc/passwd
awk -F: '$3>5{a++;print NR,$0} END{print a}' /etc/passwd
find $(echo $PATH | tr ":" "\n") -type f -name "???" 1> command 2>/dev/null;wc -l command
http://post.cbl.org/index.html
awk -F "/" '{a[$3]++} END{for(i in a){print i,a[i]}}' test
111 222 333 444 222 222 111 111 11 11
22 33 44 55 33 33 55 22
77 88 77 77 88 99 33 33
awk '{for(i=1;i<=NF;i++)a[$i,NR]++} \
{for (j in a) {split(j,m,SUBSEP);if(m[2]==NR)printf m[1]" "} printf "\n"}' test
l a[$i,NR]:二維數組
l for (j in a):遍歷,j是二維數組
l split(j,m,SUBSEP):切割二維數組,SUBSEP是切割二維數組的分隔符
l printf m[1]:若是使用print,則每一個m[1],都會自動換行。printf不會,print須要自定義格式
lprintf "\n":換行。awk是一行一行處理的,一行處理完,換行,美化輸出