天天看點

高效awk程式設計第四版學習筆記

How to Run awk Programs

文法:

awk 'program' input-file1 input-file2 适用于短program

awk -f program-file input-file1 input-file2 用在長program

awk是輸入驅動的,也就是說沒有輸入就結束

awk模型:把輸入的每一行進行檢查是否滿足pattern,如果滿足就執行action,如果不滿足,下一行處理,直到檔案的末尾。另外一種模式就是BEGIN和END,這兩個在主循環體内隻執行一次。

Running Long Programs時

awk -f source-file input-file1 input-file2

eg:BEGIN { print "Don't Panic!" }将此語句寫入advice檔案,然後執行awk -f advice

does the same as this one: awk 'BEGIN { print "Don\47t Panic!" }'

Exec awk Programs

使用檔案寫programs時,.awk檔案要寫明"#!" like this file:

#! /bin/awk -f 

BEGIN { print "Don't Panic!" }

$chmod +x advice

$advice

Don't Panic!

如果$PATH沒有也就是直接敲advice不行,你就需要./advice執行

awk is an interpreted language so used "#!"

Comments in awk Programs 在awk中注釋 # like this

# This program prints a nice,friendly message. It helps

# keep novice users from begin afraid of the computer.

但是寫在短program後面的注釋就有文法錯誤 eg: awk 'BEGIN { print "hello" } #let's be cute' 

shell quoting issues 單引号開始結束'',裡邊的顯示用雙引号"",如果使用了雙引号開始與結束,那麼裡邊的print顯示要用\"轉義雙引号,like this

awk 'BEGIN { print "Don\47t Panic!"}'

awk "BEGIN { print \"Don't Panic!\"}"

FS note 以及多重引号問題

awk -FS"" '{ print "hello" } wrong

awk -FS "" '{ print "hello" } right

Amelia    555-5553 [email protected]    F

Anthony  555-3412 [email protected]    A

Bill            555-7685 [email protected]            A

Jan    13    25    15    115

Feb    15    32    24    226

Mar    15    24    34    228

Apr    31    52    63    420

比對li并顯示 

模式比對即parttern有以下幾種:

正規表達式 /^r/

表達式 length($0) >100 $6 == "Nov"

比對$0 ~ "a"

awk '/li/{print $0}' mail-list

awk 'length($0) >80' data 預設awk不寫print也會執行print $0

awk '{ if(length($0)  >max) max = length($0)}END{print max}' date 列印最大長度的變量

awk '{ if(x <length($0)) x=length($0)} END{print mix}' data 列印最小的那個 

awk 'NF > 0' data  列印每一行

awk 'BEGIN { for (i=1;i<=7;i++) print int(101*rand())}' 列印7個0-100随機數

ls -l | awk '{x+=$5} END{print "total K-bytes : " x/1024}' 列印總位元組數

awk -F ":" '{ print $1}' /etc/passwd | sort 列印排序後使用者名

awk 'END{print NR}' data 列印檔案總行數差別于FNR

awk 'NR%2==0' data列印偶數行

以上都是單一規則rules

awk '/12/ {print $0};/21/{print $0}' mail-list inventory-shipped

有兩個規則,那麼如果一條資料既滿足12又滿足21,那麼就會顯示兩條一樣資料

A More Complex Example 

ls -l | awk '$6 == "Nov" {sum+=5;} END{print sum}' 

調用awk

awk [options] -f progfile [--] file ...

awk [options] [--] 'program' file ...

标準參數

-F --field-separator

-f --source-file

-v --var=val

讀取标準輸入和其他檔案的時候用,用“-”參數like this:

some_command | awk -f myprog.awk file1 - file2

先讀取file1 然後讀取some_command的輸入 再讀取file2

http://www.iqiyi.com/v_19rrlyojhc.html?vfm=m_332_bing引入其他的檔案  @include  "filename"

namely test1 and test2

test1 script:

BEGIN { print "This is script test1" }

and here is test2:

@include "test1"

BEGIN { print "This is script test2." }

$gawk -f test2

This is script test1

This is script test2

How to Use 有規律的表達式

文法:exp ~ /regexp/

awk '$1 ~ /J/' inventory-shipped 第一個字段比對“J”

like this :  awk '{ if ($1 ~ /J/) print }' inventory-shipped

文法:exp !~ /regexp/

awk '$1 !~ /J/' inventory-shipped 第一個字段不比對“J”

Escape Sequences 在輸出 ” 跟 \ 時候一定要用 \ 進行轉義

必備一些正則知識,...{n,m} + * ? |

-F 指定這些為分隔符時用 \進行轉義 \ ] - ^ put a '\' in front of it

eg: [d\]] 指定以d分割或者]分割

echo 'xxAA xxBxx C' | gawk -F '(^x+)|( +)' '{for (i=1;i<=NF;i++) printf "--->%s<--",$i}'

指定多個分隔符以後,首先判斷空格,如果沒有再以表達式為準,以設定的最多為準,輸出

--><--

-->AA<--

-->xxBBxx<--

-->C<--

OFS ORS FS RS

print items >> output-file

print items | command

print items |  & command

awk '{ print $1 > "names.unsorted" 

command = "sort -r > names.sorted"

print $1 | command }' mail-list

/dev/stdin The standard input (file descriptor 0)

/dev/stdout The standard output (file descriptor 1)

/dev/stderr The standard error output (file descriptor 2)

close(filename)

close(command)

不能擷取以上兩個函數的傳回值,如果擷取會報錯

"sort -r names" | getline foo 

then you must close it with this:

close("sort -r names")

本文轉自 aklaus 51CTO部落格,原文連結:http://blog.51cto.com/aklaus/1844722