跳轉到內容

AWK

25% developed
來自華夏公益教科書,開放的書籍,為開放的世界
(重定向自 Awk)

此參考文件針對的是具備一定 UNIX 使用經驗的使用者,他們剛遇到一個問題,並且被建議使用 awk 來解決它。有關 awk 的更多資訊,請參閱 Awk Primer.

以下是 awk 的主要版本

  • awk 或 Bell Labs awk
  • nawk 或 new awk
  • gawk (GNU awk)
  • mawk

nawk 和 gawk 都可以執行 awk 程式,無需修改。

獲取 AWK:如果您使用的是 Linux 或 macOS,那麼您已經擁有 AWK。對於 MS Windows,GNU awk 的版本可從 ezwinportsGnuWin32 專案Cygwin 獲取。

Awk 從檔案或標準輸入讀取資料,並將輸出到標準輸出。通常您需要將其重定向到檔案,但在這些示例中沒有這樣做,只是為了節省空間。awk 不適用於非文字檔案,例如可執行檔案和 FrameMaker 檔案。如果您需要編輯這些檔案,請使用二進位制編輯器,例如 emacs 中的 hexl-mode。

學習 awk 時的困難之一是如何讓您的程式透過 shell 的解析器。正確的方法是在程式周圍使用單引號,如下所示

>awk '{print $0}' filename

單引號可以保護幾乎所有內容免受 shell 的影響。在 csh 或 tcsh 中,您仍然需要小心感嘆號,但除此之外,您就很安全了。

學習 awk 時的另一個困難之處在於它提供的錯誤資訊。

awk '{print $0,}' filename
awk: syntax error near line 1
awk: illegal statement near line 1

gawk 通常會提供更好的錯誤資訊。至少它會告訴您錯誤發生在程式碼的哪一行。

gawk '{print $0,}' filename
gawk: cmd. line:1: {print $0,}
gawk: cmd. line:1:           ^ parse error

因此,如果您在使用 awk 語法時遇到問題,可以先嚐試使用 gawk。

一些基礎知識

[編輯 | 編輯原始碼]
  • Awk 識別“檔案”、“記錄”和“欄位”的概念。
  • 檔案由記錄組成,預設情況下記錄就是檔案中的每一行。一行就成為一條記錄。
  • Awk 每次只操作一條記錄。
  • 記錄由欄位組成,預設情況下欄位由任意數量的空格或製表符分隔。
  • 第 1 個欄位使用 $1 訪問,第 2 個欄位使用 $2 訪問,以此類推。$0 指的是整個記錄。

一些示例

[編輯 | 編輯原始碼]

學習 awk 的最快方法之一就是看一些示例程式。上面的程式將列印整個檔案,就像 cat(1) 一樣。以下是其他一些程式,以及它們的作用的簡要描述。

>awk '{print $2,$1}' filename

將列印第二個欄位,然後是第一個欄位。所有其他欄位都會被忽略。

>awk '{print $1,$2,sin($3/$2)}' filename

將列印第一個和第二個欄位,然後列印第三個欄位除以第二個欄位的正弦值。因此,第二個和第三個欄位必須是數字。Awk 有其他內建的數學函式,例如正弦函式;請閱讀手冊頁以瞭解這些函式。

"我仍然經常使用 awk '{print $1}'。"
PERL 的發明者,Larry Wall (lwall@netlabs.com)

如果您不想將程式應用於檔案的每一行怎麼辦?例如,您可能只想處理第一個欄位大於第二個欄位的行。以下程式可以實現這一點

>awk '$1 > $2 {print $1,$2,$1-$2}' filename

花括號外的部分稱為“模式”,花括號內的部分稱為“操作”。比較運算子包括 C 中的運算子

== != < > <= >= ?:

如果沒有指定模式,那麼操作將應用於所有行。我們在上面的示例程式中使用了這一事實。如果沒有指定操作,那麼將列印整行。如果單獨使用 "print",那麼將列印整行。因此,以下幾種方式是等效的

awk '$1 > $2'           filename
awk '$1 > $2{print}'    filename
awk '$1 > $2{print $0}' filename

一行中的各個欄位也可以被視為字串而不是數字。要將欄位與字串進行比較,可以使用以下方法

> awk '$1=="foo"{print $2}' filename

正則表示式

[編輯 | 編輯原始碼]

如果您想要包含某個特定字串的行怎麼辦?只需將一個 正則表示式(以 egrep(1) 的方式)放到模式中,如下所示

>awk '/foo.*bar/{print $1,$3}' filename

這將列印所有包含單詞 "foo" 以及隨後包含單詞 "bar" 的行。如果您只想列印第二個欄位中包含 "foo" 的行,可以使用 ~(“包含”)運算子

>awk '$2~/foo/{print $3,$1}' filename

如果您想要列印第二個欄位中不包含 "foo" 的行,可以使用否定 ~ 運算子,即 !~

>awk '$2!~/foo/{print $3,$1}' filename

此運算子可以理解為“不包含”。

布林值

[編輯 | 編輯原始碼]

您可以使用 C 中的布林運算子來建立複雜的模式,這些運算子包括 ! 表示“非”,&& 表示“與”,|| 表示“或”。可以使用括號進行分組。

開始和結束

[編輯 | 編輯原始碼]

有三種特殊形式的模式不符合以上描述。一種是正則表示式的開始-結束對。例如,要列印包含 "foo" 和 "bar" 的行(包括這些行本身),可以使用以下程式碼

>awk '/foo/,/bar/' filename

開始和結束

[編輯 | 編輯原始碼]

另外兩種特殊形式與此類似;它們是 BEGIN 和 END 模式。與 BEGIN 模式關聯的任何操作都將在任何逐行處理之前發生。與 END 模式關聯的操作將在所有行處理完畢之後發生。

但是,如何在一個 awk 程式中新增多個模式-操作對呢?您可以選擇幾種方法。其中一種是將它們直接組合在一起,如下所示

 > awk 'BEGIN{print"fee"} $1=="foo"{print"fi"}
        END{print"fo fum"}' filename

另一種選擇是將程式寫入檔案,如下所示

BEGIN{print"fee"}
$1=="foo"{print"fi"}
END{print"fo fum"}

假設該檔名為 giant.awk。現在,使用 awk 的 "-f" 標誌執行它

> awk -f giant.awk filename

第三種選擇是建立一個自己呼叫 awk 的檔案。以下形式可以實現

#!/usr/bin/awk -f
BEGIN{print"fee"}
$1=="foo"{print"fi"}
END{print"fo fum"} 

如果我們將此檔案命名為 giant2.awk,可以透過以下方式執行它:首先授予其執行許可權,

> chmod u+x giant2.awk

然後直接呼叫它

> ./giant2.awk filename

awk 有變數,這些變數可以是實數或字串。例如,以下程式碼列印第五列的執行總和

> awk '{print x+=$5,$0 }' filename

這在檢視 "ls -l" 的檔案大小時很有用。它在平衡支票簿時也很有用,如果支票金額儲存在一列中。

awk 變數在第一次使用時會被初始化為零或空字串。當然,哪個值取決於使用方式。

變數也可以用於儲存中間值。此示例還介紹了使用分號分隔語句

 > awk '{d=($2-($1-4));s=($2+$1);print d/sqrt(s),d*d/s }' filename

請注意,最後的語句,在本例中為“print”,不需要分號。不過,加上它也不會造成任何傷害。

  • 整數變數可以用來引用欄位。如果一個欄位包含有關哪個其他欄位重要的資訊,此指令碼將僅列印重要欄位。
 > awk '{imp=$1; print $imp }' filename
  • 特殊變數 NF 會告訴您此記錄中有多少個欄位。此指令碼將列印每個記錄的第一個和最後一個欄位,無論有多少個欄位。
 > awk '{print $1, $NF}' filename
  • 特殊變數 NR 會告訴您這是第幾條記錄。每次讀取新記錄時,它都會遞增。這提供了一種為檔案新增行號的簡單方法。
 > awk '{print NR, $0}' filename

當然,還有許多其他方法可以使用各種 UNIX 實用程式在檔案上新增行號。這留作讀者的練習。

  • 特殊變數 FS(欄位分隔符)決定 awk 將如何將每個記錄拆分為欄位。此變數可以在命令列上設定。例如,/etc/passwd 的欄位以冒號分隔。
 > awk -F: '{print $1,$3 }' /etc/passwd
此變數實際上可以設定為任何正則表示式,類似於 egrep(1)。

各個欄位也是變數,您可以為它們賦值。如果要從每行中刪除第 10 個欄位,您可以透過使用 for 迴圈列印第 1 到 9 個欄位,然後從第 11 個欄位開始(參見下文)來實現。但是,這樣做會非常簡單。

 > awk '{$10=""; print }' filename

在許多方面,awk 類似於 C。存在“for”、“while”、“do-while”和“if”結構。語句可以用花括號分組。此指令碼將列印每個記錄的每個欄位,每個欄位佔一行。

 > awk '{for(i=1;i<=NF;i++) print $i }' filename

如果您想生成比“print”語句提供的格式更漂亮的格式,您可以像在 C 中一樣使用“printf”。這是一個將第一個欄位視為字串,然後進行一些數字處理的示例。

 > awk '{printf("%s %03d %02d %.15g\n",$1,$2,$3,$3/$2); }' filename

使用 printf 時,您需要顯式換行符。

我們可以使用“printf”在不換行的情況下列印內容,這對於按反序列印記錄欄位,每行一個記錄很有用。

 > awk '{for(i=NF;i > 0;i--) printf("%s",$i); printf("\n"); }' filename

關聯陣列

[edit | edit source]

awk 有關聯陣列,由字串索引。它沒有 C 語言中陣列的直接類似物。字串索引的關聯陣列本身很有用,但將它們用作普通陣列很麻煩。

例如,我們可以統計文件中單詞的出現頻率(忽略列印它們的令人討厭的部分)。

> awk '{for(i=1;i <=NF;i++) freq[$i]++ }' filename

該陣列將為檔案中出現的每個單詞儲存一個整數值。不幸的是,這將把“foo”、“Foo”和“foo,”視為不同的單詞。好吧。我們如何列印這些頻率?awk 有一個特殊的“for”結構,它遍歷陣列中的值。此指令碼比大多數命令列長,因此它將表示為可執行指令碼。

#!/usr/bin/awk -f
{for(i=1;i <=NF;i++) freq[$i]++ }
END{for(word in freq) print word, freq[word]  }

這個遍歷陣列的迴圈似乎沒有特定的順序。因此,此類程式的輸出通常需要透過 sort(1) 進行管道傳輸才能變得有用。

多維陣列以一種奇怪的方式實現。給定的索引將連線在一起(使用特殊分隔符)以獲得一個字串,並將其用作索引。此程式將列印單詞對頻率。

#!/usr/bin/awk -f
{for(i=1;i < NF;i++) freq[$i,$(i+1)]++ }
END{for(words in freq) print words, freq[words]  }

不幸的是,這將打印出分隔符,預設情況下它不是常用字元。您可以透過使用 nawk 或 gawk 為變數 SUBSEP 賦值一個邏輯值(例如空格)來更改此設定(在普通的 awk 中不允許這樣做)。

#!/usr/bin/awk -f
BEGIN{SUBSEP=""}
{for(i=1;i < NF;i++) freq[$i,$(i+1)]++}
END{for(words in freq) print words, freq[words] }

不幸的是,這不能讓您單獨引用索引。這個技巧是使用“split”函式,它將字串分解為陣列。

#!/usr/bin/awk -f
BEGIN{SUBSEP="" }
{for(i=1;i < NF;i++) freq[$i,$(i+1)]++}
END{ for(words in freq)
     {
        split(words,word,SUBSEP); 
        print word[1], freq[words],word[2];
     } 
   }

連結

排序

[edit | edit source]

普通的 awk 沒有內建函式來排序陣列。但是,gawk 有asort(按值排序)和asorti(按索引排序,也稱為鍵)函式。asort 會丟失原始索引,用 1 到 length 索引代替。

連結

來自檔案的程式碼

[edit | edit source]

當您在檔案中使用 awk 指令碼時,可以將您的程式分解為多行,使其更容易閱讀。註釋以與 sh 程式設計相同的方式開始,使用 #。

#!/usr/bin/awk -f
# this program prints the frequencies of word pairs
BEGIN{SUBSEP=""} # set the index separator 
                 # to a nice character
{for(i=1;i < NF;i++) freq[$i,$(i+1)]++}
END{ for(words in freq)
     {
# just to show we can put a comment in here.
       split(words,word,SUBSEP); # or here
       print word[1], freq[words],word[2];
     } 
}		

您可以使用 awk 建立文字,以及處理現有文字。它對於快速生成函式值的表格很有用,而無需編譯 C 程式的麻煩。例如,它可以顯示 sin(x)/x 隨著 x 接近零而接近 1。

> awk '{x=1.0/NR; print x,sin(x)/x;}'

每次讀取新行時都會列印一個新值。因此,您可以一直按回車鍵,直到獲得所有需要的值。或者,如果您需要固定數量的值,可以這樣做。

> awk 'BEGIN{for(i=1;i <=30;i++){x=1.0/i;print x,sin(x)/x;}}' /dev/null

其中 30 是固定數量的值。

標點符號

[edit | edit source]
  • {} : 用於圍繞操作,以及在操作中對語句進行分組。
  • $ : 表示一個欄位。$1 是第一個欄位,$0 是整個記錄。
  • ~ : “包含”運算子。“foobar”~"foo" 為真。僅適用於字串。
  • !~ : “不包含”運算子。僅適用於字串。
  • == : 等於運算子。適用於數字或字串。
  • < > <= >= != : 不等運算子。適用於數字或字串。
  • # : 註釋開始字元。
  • , : 在“print”或“printf”語句中分隔內容。
  • ; : 分隔語句。
  • // : 用於圍繞正則表示式。
  • && : 布林與。
  • || : 布林或。
  • ! : 布林非。
  • () : 用於對布林表示式進行分組,向函式傳遞引數,以及在“for”、“while”等條件周圍。

程式碼生成示例

[edit | edit source]

Awk 可用於生成不想手動輸入的 C 程式碼。例如,此指令碼將生成顯式的 3x3 矩陣乘法例程。

gawk 'BEGIN{
        for(i=0;i<3;i++)
         for(j=0;j<3;j++){
           printf("d[%d][%d]=",i,j);
           for(k=0;k<3;k++){
             printf("l[%d][%d]*r[%d][%d]%s",
                    i,k,k,j,(k<2)?"+":";\n");
           }
         }
     }'

大型示例

[edit | edit source]

現在來看看一個大型示例。

# This awk program collects statistics on two 
# "random variables" and the relationships 
# between them. It looks only at fields 1 and 
# 2 by default Define the variables F and G 
# on the command line to force it to look at
# different fields.  For example: 
# awk -f stat_2o1.awk F=2 G=3 stuff.dat \
# F=3 G=5 otherstuff.dat
# or, from standard input: 
# awk -f stat_2o1.awk F=1 G=3
# It ignores blank lines, lines where either 
# one of the requested fields is empty, and 
# lines whose first field contains a number 
# sign. It requires only one pass through the
# data. This script works with vanilla awk 
# under SunOS 4.1.3.
BEGIN{
  F=1;
  G=2;
}
length($F) > 0 && \
length($G) > 0 && \
$1 !~/^#/ {
  sx1+= $F; sx2 += $F*$F;
  sy1+= $G; sy2 += $G*$G;
  sxy1+= $F*$G;
  if( N==0 ) xmax = xmin = $F;
  if( xmin > $F ) xmin=$F;
  if( xmax < $F ) xmax=$F;
  if( N==0 ) ymax = ymin = $G;
  if( ymin > $G ) ymin=$G;
  if( ymax < $G ) ymax=$G;
  N++;
}
 
END {
  printf("%d # N\n"   ,N   );
  if (N <= 1) 
    {
    printf("What's the point?\n");
    exit 1;
    }
  printf("%g # xmin\n",xmin);
  printf("%g # xmax\n",xmax);
  printf("%g # xmean\n",xmean=sx1/N);
  xSigma = sx2 - 2 * xmean * sx1+ N*xmean*xmean;
  printf("%g # xvar\n"         ,xvar =xSigma/  N  );
  printf("%g # xvar unbiased\n",xvaru=xSigma/(N-1));
  printf("%g # xstddev\n"         ,sqrt(xvar ));
  printf("%g # xstddev unbiased\n",sqrt(xvaru));
  
  printf("%g # ymin\n",ymin);
  printf("%g # ymax\n",ymax);
  printf("%g # ymean\n",ymean=sy1/N);
  ySigma = sy2 - 2 * ymean * sy1+ N*ymean*ymean;
  printf("%g # yvar\n"         ,yvar =ySigma/  N  );
  printf("%g # yvar unbiased\n",yvaru=ySigma/(N-1));
  printf("%g # ystddev\n"         ,sqrt(yvar ));
  printf("%g # ystddev unbiased\n",sqrt(yvaru));
  if ( xSigma * ySigma <= 0 )
    r=0;
  else 
    r=(sxy1 - xmean*sy1- ymean * sx1+ N * xmean * ymean)
      /sqrt(xSigma * ySigma);
  printf("%g # correlation coefficient\n", r);
  if( r > 1 || r < -1 )
    printf("SERIOUS ERROR! CORRELATION COEFFICIENT");
    printf(" OUTSIDE RANGE -1..1\n");

  if( 1-r*r != 0 )
    printf("%g # Student's T (use with N-2 degfreed)\n&", \
      t=r*sqrt((N-2)/(1-r*r)) );
  else
    printf("0 # Correlation is perfect,");
    printf(" Student's T is plus infinity\n");
  b = (sxy1 - ymean * sx1)/(sx2 - xmean * sx1);
  a = ymean - b * xmean;
  ss=sy2 - 2*a*sy1- 2*b*sxy1 + N*a*a + 2*a*b*sx1+ b*b*sx2 ;
  ss/= N-2;
  printf("%g # a = y-intercept\n", a);
  printf("%g # b = slope\n"      , b); 
  printf("%g # s^2 = unbiased estimator for sigsq\n",ss);
  printf("%g + %g * x # equation ready for cut-and-paste\n",a,b);
  ra = sqrt(ss * sx2 / (N * xSigma));
  rb = sqrt(ss       / (    xSigma));
  printf("%g # radius of confidence interval ");
  printf("for a, multiply by t\n",ra);
  printf("%g # radius of confidence interval ");
  printf("for b, multiply by t\n",rb);
}

此文件最初由 Andrew M. Ross 編寫。它可以在 這裡找到,並且由 Harvey Mudd College 計算機科學系根據 GFDL 釋出。

選項

[edit | edit source]

awk 的命令列選項,也稱為開關。

  • -F field-separator: 使用欄位分隔符正則表示式來分隔欄位。
  • -f source-file
  • -v var=val: 將變數設定為該值。由 POSIX 定義;在原始 awk 中不存在。

GNU awk 的命令列選項,也稱為開關,超出了基本的 awk。

  • -W gawk-opt
  • ...
  • --posix
  • ...

連結

數學

[edit | edit source]

支援常用的運算子 +、-、*、/、 %、^;gawk 支援 **,但 POSIX awk 不支援。內建數學函式包括 exp、log、sqrt、sin、cos、atan2、rand、srand 和 int。

數字文字為十進位制;它們可以在 C 語言風格中使用十六進位制和八進位制,在 gawk 中使用 GNU 擴充套件。

連結

使用者定義函式

[edit | edit source]

使用者定義函式可以按以下方式定義。

  • function plus(x,y) { return x+y }

一些 awk 實現(包括 gawk)允許使用“func”代替“function”,但這不符合 POSIX 標準。

支援遞迴。

  • awk 'function fact(x) { if (x > 1) { return x*fact(x-1) } else return 1} BEGIN{print fact(4)}'

連結

位操作

[編輯 | 編輯原始碼]

傳統的 awk 沒有位運算子來提供位操作。然而,gawk 內建了位操作函式,包括 and()、or()、xor()、compl()、lshift() 和 rshift()。

連結

包含庫

[編輯 | 編輯原始碼]

傳統的 awk 無法在 awk 程式中包含或匯入函式庫;最接近的方法是多次使用 -f 選項。相反,gawk 提供了這種可能性作為 GNU 擴充套件,使用 @include 關鍵字。

只要包含庫檔案的目錄在 AWKPATH 環境變數中,就不需要指定庫檔案的完整路徑。設定 AWKPATH 可防止 awk 將當前目錄視為路徑的一部分,除非 AWKPATH 包含句點 (.) 來表示當前目錄。AWKPATH 的專案分隔符是冒號 (:),或 Windows 上的分號 (;)。

也可以透過 gawk 的 -i 選項載入 awk 函式庫。因此,如果您有檔案 lib.awk,該檔案所在目錄的路徑在 AWKPATH 中,並且該檔案定義了 abs 函式,您可以像這樣呼叫 gawk

  • awk -ilib "BEGIN {print abs(-4)}"

您無法使用 -f 選項執行此操作;您必須將主程式儲存在單獨的檔案中,然後在同一命令列上兩次使用 -f 選項,第一次載入庫,第二次載入主程式。

可以在 GitHub 上的 Many AWK 專案中找到許可自由的 awk 庫。

連結

單行示例

[編輯 | 編輯原始碼]

awk 使用的單行示例

  • echo abcd |awk '/b.*d/'
    • 輸出與正則表示式匹配的行,類似 grep 命令。
  • echo abcd |awk '/b.*d/ {print $0}'
    • 與上面相同,但使用顯式列印語句。$0 代表整行。
  • echo ab   cd |awk '/b.*d/ {print $2}'
    • 對於與正則表示式匹配的行,輸出第二欄位。預設情況下使用空格序列作為欄位分隔符。因此,輸出“cd”。
  • echo abcd,e |awk -F, '/b.*d/ {print $2}'
    • 對於與正則表示式匹配的行,輸出第二欄位,由於 -F 選項,使用逗號作為欄位分隔符。因此,輸出“e”。
  • echo abcd,e |awk '{print toupper($0)}'
    • 輸出所有行的大寫字母。對於小寫字母,使用“tolower”。
  • echo a b c d | awk '{print $NF, $(NF-1)}'
    • 輸出最後一個欄位和倒數第二個欄位;NF 是欄位數量。
  • echo ab cd | awk 'NF>=2'
    • 輸出欄位數量為 2 或更大的行。
  • echo ab cd | awk '{print NF}'
    • 對於每一行,輸出該行中的欄位數量。
  • echo ab cd | awk 'length($2) > 1'
    • 輸出第二欄位長度大於 1 的所有行。
  • echo ab cd | awk '$2 ~ /cd/'
    • 輸出第二欄位與正則表示式匹配的所有行。
  • echo ab cd | awk '$1 ~ /ab/ && $2 ~ /cd/'
    • 與上面類似,但使用兩個由“&&”連線的子條件。支援 C 程式語言中已知的其他一些邏輯運算子。
  • cat file.txt | awk 'NR >= 100 && NR <= 500'
    • 輸出行號在指定範圍內的行(記錄)。因此,充當行號過濾器。
  • cat file.txt | awk 'NR == 1 || /reg.*pattern/'
    • 輸出第一行和與正則表示式匹配的行。
  • echo abcd | awk '{gsub(/ab/,"ef");print}'
    • 替換,也稱為替換,類似於 sed 命令;gsub 中的“g”代表全域性。
  • awk 'BEGIN{for(i=1;i<6;i++) print sqrt(i)}'
    • 輸出 1、…、5 中整數的平方根。使用 BEGIN{} 可確保程式碼無論是否將任何輸入行饋送到 awk 都能執行。for 迴圈使用熟悉的 C 語言語法,sqrt 是多個可用數學函式之一。
  • awk 'BEGIN{printf "%i %.2f\n", 1, (2+3)/7}'
    • 支援來自 C 語言的熟悉函式 printf,作為不需要在引數周圍使用括號的語句。
  • awk 'BEGIN{for(i=1;i<9;i++) a[i]=i^2; for(i in a) print i, a[i]}'
    • 藉助 awk 關聯陣列(也稱為對映或字典),輸出幾個整數及其平方。輸出的順序是不確定的,這在關聯陣列中很常見。awk 沒有其他程式語言中已知的陣列和列表的直接對應物。
  • cat file.txt | awk '{sum+=$1} END{print sum}'
    • 使用 END 關鍵字輸出第一欄位(列)中值的總和。
  • printf 1,2,3\\n4,5,6 | awk -F, '{s=0;for(i=1; i<=NF; i++) {s+=$i} print s}'
    • 對於逗號分隔檔案的每一行,輸出該行中欄位(列)的總和。因此,遍歷欄位。
  • echo 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 | awk -F, -vn=7 '{for(i=1;i<=NF; i++) {s+=i>n?$i-$(i-n):$i; if(i>=n){printf "%.0f, ", s/n}else{printf ", "}}}'
    • 輸出逗號分隔的輸入逗號分隔序列的 7 值簡單移動平均值。
  • awk 'BEGIN{system("dir")}'
    • 執行外部命令 dir;在沙箱模式下停用。
  • awk 'function abs(x) {return x < 0 ? -x : x} BEGIN{print abs(-4)}'
    • 定義並使用絕對值函式。顯示了來自 C 語言的三元運算子的使用。

連結

線上嘗試

[編輯 | 編輯原始碼]

您可以在 http://awk.js.org/ 上線上嘗試 awk。關鍵詞:REPL 線上。

侷限性

[編輯 | 編輯原始碼]

與其他指令碼語言相比,AWK 的侷限性包括以下內容

  • 沒有其他程式語言中已知的陣列和列表的直接對應物,只有關聯陣列。
  • 沒有巢狀陣列:關聯陣列的值不能是陣列。
  • 沒有真正的多維陣列:多個索引儲存為透過分隔符連線索引而形成的單個索引。
  • 在普通 awk 中沒有陣列的排序函式,只有在 gawk 中有。
  • 在普通 awk 中沒有位運算子;gawk 有位操作函式,包括 and()、or()、compl() 等。
  • 在傳統的 awk 中不支援包含要由 awk 指令碼重用的函式的庫或模組;但是,gawk 支援用於該目的的 @include 關鍵字。
  • 不支援 GUI 程式設計。

連結

原始碼

[編輯 | 編輯原始碼]

各種版本的 awk 的原始碼

另請參見

[編輯 | 編輯原始碼]
  • O'Reilly 的 sed & awk 袖珍參考
  • UNIX 概覽
  • UNIX 權力工具
[編輯 | 編輯原始碼]
華夏公益教科書