awk-實踐

實際中遇到的問題

  1. 字符串截取函數 substr
    #!/usr/bin/awk
    #author:zhaoyingnan
    #filename:substr.awk
    #substr 函數
    #echo 20150627185312|awk -f substr.awk
    {
        #格式化時間格式
        #索引1開始
        print substr($0,1,4)"-"substr($0,5,2)"-"substr($0,7,2)" "substr($0,9,2)":"substr($0,11,2)":"substr($0,13,2);
        printf "%04d-%02d-%02d %02d:%02d:%02d\n",substr($0,1,4),substr($0,5,2),substr($0,7,2),substr($0,9,2),substr($0,11,2),substr($0,13,2);
    }
  2. 替換函數 sub 和 gsub
    #!/usr/bin/awk -f
    #author:zhaoyingnan
    #filename:sub.awk
    #sub 替換函數
    #2016-06-27 15:33:51 current_query => [SELECT * FROM `zhs_user_timeline_147` WHERE  1  and `id`>=294037031 limit 1000]
    BEGIN{
        FS="[ `>]";
    }
    {
        #刪除`
        $0 == sub(/`/, "", $0);
        print $0;
        #sub只會替換模式匹配到的第一個匹配
        #至關於vi裏面的 %s/apple/banana/
        #至關於sed 's/apple/banana/'
    }
    #!/usr/bin/awk -f
    #author:zhaoyingnan
    #filename:gsub.awk
    #gsub 替換函數
    #2016-06-27 15:33:51 current_query => [SELECT * FROM `zhs_user_timeline_147` WHERE  1  and `id`>=294037031 limit 1000]
    BEGIN{
        FS="[ `>]";
    }
    {
        #刪除`
        $0 == gsub(/`/, "", $0);
        print $0;
        #sub會替換模式匹配到的全部的匹配
        #至關於vi裏面的 %s/apple/banana/g
        #至關於sed 's/apple/banana/g'
    }

     

  3. NR和FNR,首先,如果讀取一個文件的話,他們是同樣的,如果讀取多個文件,NR是這幾個文件行數的總和,但FNR則在每次讀取新的文件時都會從1開始.
  4. 使用awk 將文件中的時間戳轉化爲日期,可使用system調用date
    1 echo 1444440491|awk '{system("date -d @\""$0"\" \"+%F %T\"")}'
    2 2015-10-10 09:28:11

  5. 打印指定的字段到最後(使用循環)
    ps -ef |grep '/usr/local/php/bin/php excute.php' --color|awk '{ if(NF>=15){ for(i=10;i<=NF;i++){ if(NF==i){ printf "%s\n",$i; }else{ printf "%s ",$i; } } } }'|awk '{ for(i=1;i<=NF;i++){ print $i; } }'|sort -n -t _ -k 5|wc -l

     

  6. 打印出在指定範圍內不存在的行(使用數組)
     1 #!/bin/awk -f
     2 #author:zhaoyingnan
     3 BEGIN{
     4     for(i=0;i<=499;i++)
     5     {
     6         num[i]=i;
     7     }
     8 }
     9 {
    10     exists[$0]=$0;
    11 }
    12 END{
    13     for(j in num)
    14     {
    15         if(num[j] in exists)
    16         {
    17         }
    18         else
    19         {
    20             print "db_community=>zhs_user_timeline_"num[j]" is end";
    21         }
    22     }
    23 }
  7. 指定多個分隔符時,最好不要偷懶,須要寫成 -F "[.......]"
    1 #!/bin/bash
    2 #批量修改文件
    3 #oldsix-11.html  -> linux-11.HTML
    4 for file in `ls`
    5 do
    6     mv $file `echo $file|awk -F "[-.]" '{printf "%s%s%s","linux-",$2,"."toupper($3)}'`
    7 done

下面不用看php

  1 #!/usr/bin/awk -f
  2 # 在系統提示下輸入腳本
  3 # 本文爲awk筆記
  4 #
  5 # ********************************************************************************************************************************************
  6 # awk    命令格式
  7 #        awk [options] 'pattern{action}' [var1=value1 var2=value2] files
  8 #        模式部分和操做部分都是可選的.若是沒有指定模式,則操做會應用到所有的記錄[zyn1];若是沒有指定操做部分,則會輸出匹配的所有記錄.[zyn2]
  9 #        模式部分和操做部分都是能夠出現屢次.
 10 #
 11 # ********************************************************************************************************************************************
 12 #
 13 # options    選項部分
 14 #        -f    從腳本中讀取awk命令
 15 #        -F    指定多個字段分割符[zyn3]
 16 #        -v    賦值一個用戶定義變量[zyn4]
 17 #
 18 # ********************************************************************************************************************************************
 19 #
 20 # pattern    模式部分
 21 #        由某種表達式組成的語句,模式不能被括在{}內:
 22 #        BEGIN{}    指定在第一條輸入記錄被處理以前發生的動做;
 23 #        END{}    指定在最後一條輸入記錄以後發生的動做;
 24 #        判別條件真僞的表達式:~表示匹配,!~表示不匹配;字符串或數字比較;關係運算;[zyn5]
 25 #        /模式1/,/模式2/    指定一個行的範圍.[zyn6]
 26 #
 27 # ********************************************************************************************************************************************
 28 #
 29 # action    操做部分
 30 #        由{}括起的一條或多條語句組成,語句間用;或者換行符分割,默認操做是打印全部表達式結果爲真的文本行:
 31 #            格式化輸出;
 32 #            變量或數組操做;
 33 #            內置函數;
 34 #            控制流命令
 35 #
 36 # ********************************************************************************************************************************************
 37 #
 38 # 腳本文件格式
 39 #        若是同一行上有多個語句或操做,必須用;隔開;若是每條語句都在不一樣的行上,能夠不用加;
 40 #        若是操做跟在某個模式後面,它的{就必須與該模式在同一行[zyn2],[zyn5],[zyn6],[zyn7]
 41 #        註釋要一#開頭
 42 #
 43 # ********************************************************************************************************************************************
 44 #
 45 # 正則表達式元字符
 46 # ^在串首匹配        $在串尾匹配            .匹配任意單個字符        *匹配零個或多個前一個字符
 47 # +匹配一個或多個前一個字符        ?匹配零個或一個前一個字符        []匹配指定字符串組
 48 # [^]匹配任意一個不在指定字符串組        |匹配二者之一        ()+匹配一個或多個組合
 49 # &用在代替字符串中,表明查找串中匹配到的內容[zyn9]
 50 #
 51 # ********************************************************************************************************************************************
 52 #
 53 # 正則表達式POSIX字符類
 54 # [:alnum:]文字數字字符        [:alpha:]文字字符        [:digit:]數字字符        [:graph:]非空字符(包括空格)
 55 # [:punct:]標點符號        [:lower:]小寫字符        [:upper:]大寫字符        [:cntrl:]控制字符
 56 # [:space:]全部空白字符(空格,新行,製表符)        [:xdigit:]十六進制數字    [:blank:]空格和製表符
 57 #
 58 # ********************************************************************************************************************************************
 59 #
 60 # 關係運算符:<,<=,>,>=,==,!=
 61 #            ~,!~在正則中的匹配,不匹配
 62 # 條件表達式:?:三元運算符,if else
 63 # 邏輯運算符:||,&&,!
 64 # 算數運算符:+,-,*,/,%,^(求冥),&(求餘),++(一元加),--(一元減),賦值=,+=,-=,*=,/=,%=,^=,**=
 65 # 範圍:/../,/../
 66 #
 67 # ********************************************************************************************************************************************
 68 #
 69 # 影響流程控制的語句
 70 #    除了if,while,for,do以外,還有break,continue,next
 71 #        在一個循環中的兩個影響流程控制的break以及continue:break是退出循環,continue是終止當前的循環,並開始下一次的循環;
 72 #        next:能夠連續從文件讀取內容,忽略腳本的其餘操做直到文件被讀完[zyn10],[zyn11]
 73 #        exit:exit使主輸入循環退出控制,執行END{}中的操做,若是沒有END{},或者換行符分割是在END{}中應用了exit,則終止腳本執行.
 74 #
 75 # ********************************************************************************************************************************************
 76 # getline函數,注意它不用加上()
 77 #        getline函數用於從輸入中讀取下一行,它不只能讀取正常的數據流,並且能處理來自文件和管道的輸入[zyn12][zyn13]
 78 #        getline函數可能的返回值爲:1 若是可以讀取一行.0 若是到了文件末尾.-1 若是遇到錯誤
 79 #        getline函數讀取新的行以後,會將其賦值給$0,而且將其分解成字段,同時設置了系統變量NF和NR以及FNR,如若不想改變$0,可將其賦值給別的變量,可是系統變量仍是會被設置的
 80 # close()函數用於關閉打開的文件和管道
 81 #        在不一樣的系統中,能打開的管道的數量是不一樣的,可是是都有必定數量的限制的;
 82 #        關閉一個管道使得你能夠運行同一個命令兩次;[zyn13]
 83 #        關閉一個輸出管道是必要的[zyn14]
 84 # ********************************************************************************************************************************************
 85 #
 86 #
 87 # [zyn1]
 88 # awk -f awk.awk lianxi.txt
 89 #BEGIN{printf "%s\n","沒有模式部分";}
 90 #{
 91 #    print $0;
 92 #}
 93 #END{}
 94 #
 95 #
 96 # [zyn2]
 97 #BEGIN{printf "%s\n","沒有操做部分";}
 98 #$0~/^$/{
 99 #    print $0;
100 #}
101 #END{}
102 #
103 #
104 # [zyn3]
105 # echo '1,2,3,4,5,6'|awk -f awk.awk
106 #BEGIN{FS=",";OFS="-";}
107 #{
108 #    print $1,$2,$3,$4,$5;
109 #}
110 #END{}
111 #
112 #
113 # [zyn4]
114 # -v    awk -vname=$USER -f awk.awk rizhi.txt 使用的是系統變量 
115 #        awk -vname="haha" -f awk.awk rizhi.txt 自定義變量
116 #        awk -vname="haha" -vhome="gg" -f a.awk rizhi.txt    多個變量
117 # awk -vname="zhaoyingnan" -vhome="hebei" -f awk.awk lianxi.txt
118 #BEGIN{OFS="-";}
119 #{}
120 #END{printf "name:%s,home:%s",name,home;}
121 #
122 #
123 # [zyn5]
124 # 在每一個非空的行的結尾追加字符,且保留源文件的空行
125 # awk -f awk.awk lianxi_5.txt
126 #BEGIN{}
127 #$0~/^$/{
128 #    print $0;
129 #}
130 #$0!~/^$/{
131 #    print $0"<br/>";
132 #}
133 #END{}
134 #
135 #
136 # [zyn6]
137 #BEGIN{PS="\"";OFS="\T";}
138 #/<h4>/,/<\/h4>/{
139 #        print $0;
140 #        print $2;
141 #}
142 #END{}
143 #
144 #
145 # [zyn7]
146 # awk -f awk.awk lianxi6.txt
147 #BEGIN{FS="\t"}
148 #/^[A]/{
149 #    print $0;
150 #}
151 #$2~/^[rR]/{
152 #    print $0;
153 #    }
154 #$2~/^[^rR][^2].*/{
155 #    print $0;
156 #    }
157 #END{}
158 #
159 #
160 # [zyn8] fail
161 # POSIX字符類 須要開啓posix支持
162 # awk --posix -f awk.awk lianxi6.txt
163 #BEGIN{}
164 #$2~/^[rRaAbB][[:digit:]].*/{
165 #    print $0;
166 #    }
167 #END{}
168 #
169 #
170 # [zyn9] fail
171 # &使用
172 #BEGIN{}
173 #/^[rR][sS]/{
174 #    print $0;
175 #}
176 #END{}
177 #
178 #
179 # [zyn10]
180 # 將國家名稱順序修改
181 # awk -f awk.awk country.txt
182 #BEGIN{
183 #    printf "%s\t\t%s\t\t%s\t\t\n","英文全稱","英文縮寫","中文全稱";
184 #}
185 #{
186 #    if(NR%3!=0)
187 #        printf "%s\t\t",$0;
188 #    else
189 #        printf "%s\n",$0;
190 #}
191 #END{}
192 #
193 #
194 # [zyn10]
195 # 世界各中英文對照表
196 # awk -f awk.awk country_format.txt country_yingwen.txt
197 #BEGIN{FS=",";OFS="\t";}
198 #FILENAME=="country_format.txt"{
199 #    split($0,entry,",");
200 #    country[entry[1]]=entry[3];
201 #    next
202 ##    print entry[1],entry[2],entry[3];
203 #}
204 #/[A-Z][a-z]+/{
205 #    for(i=1;i<=NF;i++)
206 #    {
207 #        if($i in country)
208 #        {
209 #            $i=country[$i]"("$i")";
210 #        }
211 #    }
212 #    print $1,$2,$3;
213 #}
214 #END{}
215 #
216 #
217 # [zyn11]
218 # 星期月份對照表
219 # awk -f awk.awk week_and_month_mix.txt week_and_month_desc.txt 
220 #BEGIN{FS=",";}
221 #FILENAME=="week_and_month_mix.txt"{
222 ##week_and_month_mix/txt文件的每一行都會執行action的操做
223 #    split($0,swap,",");
224 #    week[swap[2]]=swap[3]" "swap[1];
225 #    next
226 #}
227 #/[A-Z][a-z]+[.]?/{
228 ##只有從不一樣文件輸入內容的時候纔會執行
229 #    for(i=1;i<=NF;i++)
230 #    {
231 #        if($i in week)
232 #        {
233 #            $i=$i"("week[$i]")";
234 #        }
235 #    }
236 #    print $0;
237 #}
238 #END{}
239 #
240 #
241 # [zyn12]
242 # 測試getline執行流程
243 # 
244 #BEGIN{}
245 #/^(AB).*/{
246 #    print $0;
247 #    while(getline>0)
248 #    {
249 #        if($0~/^(KL).*/)
250 #        {
251 #            a=$0;
252 #            print a;
253 #        }
254 #        else
255 #            break    
256 #    }
257 #}
258 #END{}
259 #
260 #
261 # [zyn13]
262 # getline 從管道讀入輸入
263 #BEGIN{}
264 #{
265 #    "whoami"|getline me;
266 #    close("whoami");#這裏必須將這個管道關掉,不然下面的不能用喲
267 #    "whoami"|getline my;
268 #    "pwd"|getline path;
269 #    print $0,me,my,path;
270 #}
271 #END{}
272 #
273 #
274 # [zyn14]
275 # close()關閉一個輸出管道
276 #BEGIN{filename="sort7.txt"}
277 #{
278 #    print $0|"sort > sort7.txt"
279 #}
280 #filename=="sort7.txt"{
281 #    while((getline < filename)>0)
282 #    {
283 #        print $0;
284 #    }
285 #}
286 #END{}
287 #
288 #
289 # ********************************************************************************************************************************************
290 # awk中的函數
291 # gsub(pattern,replace,subject)
292 # 在字符串subject用replace替換和正則表達式pattern相匹配的全部字符串,返回被替換的個數,若沒有提供subject則默認爲$0
293 # sub(pattern,replace,subject)
294 # 和gsub相同,不一樣的是,gsub是全部位置的替換,sub只替換第一個位置喲
295 # awk -f awk.awk 10_zhaoyingnan.log
296 #BEGIN{FS="\"";}
297 #{
298 #    sub(/\//,"_",$16);
299 #    gsub(/\//,"_",$16);
300 #    gsub(/\.[jJ][pP][Gg]/,".jpg",$16);
301 #    print $16
302 #}
303 #END{}
304 #
305 #
306 # index(subject,search)
307 # 返回子串search在subject中的位置,若沒有則返回0
308 # substr(subject,starposion,length)
309 # 返回subject中從startposion開啓,最大長度爲length的子串,若沒給出length,則返回從startposion開始到結束的子串
310 # awk -f awk.awk 10_zhaoyingnan.log
311 #BEGIN{FS="\""}
312 #{
313 #    print $16,index($16,"pai");
314 #    print $16,index($16,"suipai");
315 #    print $16,substr($16,index($16,"c180"));
316 #}
317 #END{}
318 #
319 #
320 # tolower(subject)將字符串subject中全部的大寫字符轉換爲小寫,返回新的字符串
321 # toupper(subject)將字符串subject中全部的小寫字符轉換爲大寫,返回新的字符串
322 # awk -f awk.awk 10_zhaoyingnan.log
323 #BEGIN{FS="\""}
324 #{
325 #    print $16,tolower($16),toupper($16);
326 #}
327 #END{}
328 #
329 #
330 # length(subject) 返回subject的長度,若沒有指定subject,則返回$0的長度
331 #
332 #BEGIN{FS="\""}
333 #{
334 #    print length,length($16),"中文長度"length("中文");
335 #}
336 #
337 #
338 # match(subject,pattern)
339 # 若是正則表達式pattern在subject中出現,則返回出現的啓始位置,並設置RSTART爲該位置,設置RLENGTH爲匹配字符串的字符數,不然返回0,並設置RSTART爲0,RLENGTH爲-1;
340 # echo "APPLE,PALNE"|awk -f awk.awk
341 #BEGIN{FS=","}
342 #{
343 #    for(i=1;i<=NF;i++)
344 #        print $i,match($i,/[A-Z]+/),RSTART,RLENGTH;
345 #}
346 #END{}
347 #
348 #
349 # split(subject,array,decollator)
350 # 使用分隔符decollator將subject分解到array數組中,返回元素的個數,如沒有給出decollator則使用FS
351 #BEGIN{FS=","}
352 #{
353 #    split($0,array)
354 #    for(i in array)
355 #        print array[i]
356 #}
357 #END{}

 

測試用到的文件
sed -n '/^#\s*awk.*\.[tl]/p' awk.awk |uniq
# awk -f awk.awk lianxi.txt
#        awk -vname="haha" -f awk.awk rizhi.txt 自定義變量
#        awk -vname="haha" -vhome="gg" -f a.awk rizhi.txt    多個變量
# awk -vname="zhaoyingnan" -vhome="hebei" -f awk.awk lianxi.txt
# awk -f awk.awk lianxi_5.txt
# awk -f awk.awk lianxi6.txt
# awk --posix -f awk.awk lianxi6.txt
# awk -f awk.awk country.txt
# awk -f awk.awk country_format.txt country_yingwen.txt
# awk -f awk.awk week_and_month_mix.txt week_and_month_desc.txt 
# awk -f awk.awk 10_zhaoyingnan.log
相關文章
相關標籤/搜索