awk分爲BEGIN部分,正則匹配部分,END部分三部分。html
我通常在BEGIN部分定義一些變量,正則部分用於匹配和執行一些解析和統計,END部分用於輸出結果。linux
整體結構:nginx
awk 'BEGIN{xxxx;xxxx;}{xxxx;xxxx;} /匹配字符串/{xxxx;xxxx;} END{xxxx;xxxx;}' 待處理的輸入文件 或 其餘命令的結果 | awk 'BEGIN{xxxx;xxxx;}{xxxx;xxxx;} /匹配字符串/{xxxx;xxxx;} END{xxxx;xxxx;}'
示例一:shell
抓取網頁test.html中的身份證號/手機號,輸入:一個html文件,輸出:一行:網頁url 身份證號個數 手機號個數 找到的身份證號 找到的手機號數組
cat test.html | sed -e 's/\(^\|[^0-9]\)\(13[0-9][0-9]\{8\}\|14[579][0-9]\{8\}\|15[0-3,5-9][0-9]\{8\}\|16[6][0-9]\{8\}\|17[0135678][0-9]\{8\}\|18[0-9][0-9]\{8\}\|19[89][0-9]\{8\}\)\($\|[^0-9]\)/\nfind_phone:\2\n/g' | sed -e 's/\(^\|[^0-9]\)\([0-9]\{6\}[1-2][0-9]\{3\}\(\(0[1-9]\)\|\(10\|11\|12\)\)\(\([0-2][1-9]\)\|10\|20\|30\|31\)[0-9]\{3\}[0-9Xx]\)\($\|[^0-9]\)/\nfind_idcard:\2\n/g'| awk 'BEGIN{OFS=":";idcard_count=0;phone_count=0;}/Url/{if(NR<10) {url=$3;}}/find_phone/{phone_count++;phone_list[phone_count]=$1;}/find_idcard/{idcard_count++;idcard_list[idcard_count]=$1;}END{if(idcard_count!=0||phone_count!=0){printf "%s",url;for(i=0;i<length(url)/7;i++){printf "\t"};printf "%d\t%d\t",idcard_count,phone_count;for(i=1;i<=phone_count;i++){printf phone_list[i];printf "\t";};for(i=1;i<=idcard_count;i++){printf idcard_list[i];printf "\t";};print "";}}'
示例二:bash
num.txt: 1 2 3 加法: cat num.txt | awk '{sum += $1} END {print sum}' 輸出: 6
示例三:輸入:示例一的輸出 輸出:url 是否有身份證號 是否有手機號 1條匹配到的身份證 1條匹配到的手機號less
運行命令:
輸出到文件
[spider@]$ cat sample1.output | sh test_filter.sh > sample3.output
輸出到控制檯用less查看
[spider@]$ cat sample1.output | sh test_filter.sh | less
less命令:
less命令的做用與more十分類似,均可以用來瀏覽文字檔案的內容,不一樣的是less命令容許用戶向前或向後瀏覽文件,而more命令只能向前瀏覽。用less命令顯示文件時,用PageUp鍵向上翻頁,用PageDown鍵向下翻頁。要退出less程序,應按Q鍵。
#!/bin/bash awk '{ id_num=0; phone_num=0; temp_id="NULL"; temp_phone="NULL"; for(i=4;i<NF;i++){ if($i~/find_phone/) { phone_num++; temp_phone=$i; } if($i~/find_idcard/) { if(!($i~/find_idcard:20/)) { id_num++; temp_id=$i; } } } if(id_num>0){ has_id="true" }else{ has_id="false" } if(phone_num>0){ has_phone="true" }else{ has_phone="false" } print substr($1,1,length($1)-1)"\t"has_id"\t"has_phone"\t"temp_id"\t"temp_phone }' | awk '{ if($1!="NULL" && ($2=="true" || $3=="true")) { print $0 } }'
用substr函數切掉url字符串的最後一個^M字符,防止輸出時覆蓋ide
一、使用過程當中難點主要是對不一樣行作不一樣的解析和輸出處理:函數
http://bbs.chinaunix.net/thread-4186958-1-1.htmlurl
二、
awk '{print NR}' filename; //打印行號
awk ‘{print $0}' filename; //打印整行
三、if語句
[chengmo@localhost nginx]# awk 'BEGIN{ test=100; if(test>90) { print "very good"; } else if(test>60) { print "good"; } else { print "no pass"; } }' very good
更多的if/for/while/do操做:
https://www.cnblogs.com/chengmo/archive/2010/10/04/1842073.html
四、awk的變量(包括數組)不須要聲明能夠直接使用
https://www.cnblogs.com/pangbing/p/7015745.html
五、awk中判斷字符長度: length(變量名)
http://bbs.chinaunix.net/thread-271694-1-1.html
六、查詢文件行數
[spider@zhangsuosheng]$ cat test2.html dddd bbb131102198910084421ccc eee13611112222fff13133334444 h15855556666j aaaa 13177778888 13199990000 18611112222 370785199507319527 [spider@zhangsuosheng]$ cat test2.html |awk 'BEGIN{counter=0;}{counter++;}END{print counter;}' 8
sed 's/\(.*\)/\1\n\1\n\1\n\1\n\1\n\1\n\1\n\1\n\1\n\1/g' > ${file}
#!/bin/bash file_list=('1.txt' '2.txt' '3.txt' '4.txt' ) for file in ${file_list[@]} do temp='../'${file} cat ${temp} | sed 's/\(.*\)/\1\n\1\n\1\n\1\n\1\n\1\n\1\n\1\n\1\n\1/g' > ${file} ../data_tools shuffle -if1 ${file} -of1 ${file} done
shortest match by default
把txt文件中包含test行的行尾添加 ‘000’
sed -i '/test/ s/$/000/'