日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

AWK介绍

發(fā)布時(shí)間:2025/4/14 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AWK介绍 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.awk?簡(jiǎn)介

  • awk?以記錄和字段的方式來(lái)查看文本文件

  • 和其他編程語(yǔ)言一樣,?awk?包含變量、條件和循環(huán)

  • awk?能夠進(jìn)行運(yùn)算和字符串操作

  • awk?能夠生成格式化的報(bào)表數(shù)據(jù)


  • 2.awk?概述

    awk?程序?awk?命令、括在括號(hào)(或?qū)懺谖募?#xff09;中的程序指令以及輸入文件的文件名幾個(gè)部分組成。如果沒(méi)有輸入文件,輸入則來(lái)自于標(biāo)準(zhǔn)輸入。

    awk?指令由模式、操作或者模式與操作的組合組成。模式是由某種類型的表達(dá)式組成的語(yǔ)句。如果某個(gè)表達(dá)式中沒(méi)有出現(xiàn)關(guān)鍵在?if?,但實(shí)際在計(jì)算時(shí)卻暗含?if?這個(gè)詞,那么這個(gè)表達(dá)式就是模式。操作由括在大括號(hào)中的一條或多條語(yǔ)句組成,語(yǔ)句之間用分號(hào)或者換行符隔開(kāi)。模式不能括在大括號(hào)中,模式由包括在兩個(gè)正斜杠之間的正則表達(dá)式、一個(gè)或多個(gè)?awk?操作符組成的表達(dá)式組成。

    格式:

    awk '/search pattern1/ {Actions}

    /search pattern2/ {Actions}' file


    3.?工作原理

  • awk?使用一行作為輸入(通過(guò)文件或者管道),并將這一行賦給內(nèi)部變量?$0

  • 行被空格分解為字段(單詞),每一個(gè)字段存儲(chǔ)在已編號(hào)的變量中,從?$1?開(kāi)始。(?awk的內(nèi)部變量?FS?用來(lái)確定字段的分隔符。初始時(shí),為空格,包含制表符和空格符)

  • 對(duì)于一行,按照給定的正則表達(dá)式的順序進(jìn)行匹配,如果匹配則執(zhí)行對(duì)應(yīng)的?Action?,如果沒(méi)有匹配上則不執(zhí)行任何動(dòng)作 ,?Search Pattern?和?Action?是可選的,但是必須提供其中一個(gè) 。如果?Search Pattern?未提供,則對(duì)所有的輸入行執(zhí)行?Action?操作。如果?Action?未提供,則默認(rèn)打印出該行的數(shù)據(jù) 。?{}?這種?Action?不做任何事情,和未提供的?Action?的工作方式不一樣

  • 打印字段,用?print??printf??sprintf?,格式:?{ print $1, $3 }?內(nèi)部變量?output field separator??OFS?),默認(rèn)為空格,?$n?之間的逗號(hào)被?OFS?中的字符替換。

  • 輸出之后,從文件中另取一行,并將其復(fù)制到?$0?中,覆蓋原來(lái)的內(nèi)容。重復(fù)進(jìn)行……


  • 4.?格式化輸出

    print?函數(shù)

    print?函數(shù)用于打印不需要特別編排格式的簡(jiǎn)單輸出。更為復(fù)雜的格式編排則要使用?printf??sprintf。若懂得?C?語(yǔ)言,則也一定懂得如何使用?printf??sprintf?


    print?函數(shù)的的轉(zhuǎn)義序列

    /b 退格

    /f 換頁(yè)

    /n 換行

    /r 回車

    /t 制表符

    /047 八進(jìn)制值?47?,即單引號(hào)

    /c c?代表任意其他字符

    打印數(shù)字時(shí),可能需要控制數(shù)字的格式。可以通過(guò)?printf?來(lái)實(shí)現(xiàn),但是通過(guò)設(shè)置一個(gè)特殊的變量OFMT?,是用?print?函數(shù)也可以控制數(shù)字打印格式。?OFMT?默認(rèn)為“?%.6gd”?,表示只打印小數(shù)部分的前?6?位。

    ?1?

    long@long-Ubuntu:~$ awk 'BEGIN { OFMT="%.2f"; print 1.2456789, 12E-2 }'

    1.25 0.12


    printf?函數(shù)

    printf?函數(shù)返回一個(gè)帶格式的字符串給標(biāo)準(zhǔn)輸出,如同?C?語(yǔ)言中的?printf?語(yǔ)句。?printf?語(yǔ)句包括一個(gè)加引號(hào)的控制串,控制串中可能嵌套有若干格式說(shuō)明和修飾符。控制串后面跟逗號(hào),之后是一列由逗號(hào)分隔的表達(dá)式。與?print?函數(shù)不同的是,?printf?函數(shù)不會(huì)在行尾自動(dòng)換行。若要換行,在控制串中提供轉(zhuǎn)義字符?/n?。每個(gè)百分號(hào)和格式說(shuō)明都必須有一個(gè)對(duì)應(yīng)的變量?。要打印百分號(hào)就必須在控制串中給出兩個(gè)百分號(hào)。


    p?rintf?函數(shù)的轉(zhuǎn)義字符

    c? 字符

    s? 字符串

    d? 十進(jìn)制整數(shù)

    ld 十進(jìn)制長(zhǎng)整數(shù)

    u? 十進(jìn)制無(wú)符號(hào)整數(shù)

    lu 十進(jìn)制無(wú)符號(hào)長(zhǎng)整數(shù)

    x? 十六進(jìn)制整數(shù)

    lx 十六進(jìn)制長(zhǎng)整數(shù)

    o? 八進(jìn)制整數(shù)

    lo 八進(jìn)制長(zhǎng)整數(shù)

    e? 用科學(xué)計(jì)數(shù)法表示浮點(diǎn)數(shù)

    f? 浮點(diǎn)數(shù)

    g? 選用?e??f?中較短的一種形式

    ?

    printf?函數(shù)的修飾符

    - 左對(duì)齊修飾符

    # 顯示八進(jìn)制整數(shù)時(shí),前面加 0 ,顯示十六進(jìn)制整數(shù)時(shí),前面加 0x

    + 顯示使用 d 、 e 、 f 、 g 轉(zhuǎn)換的整數(shù)時(shí),加上正負(fù)號(hào)

    0 用 0 而不是空白符來(lái)填充所顯示的值


    printf?函數(shù)控制串里的管道符(豎杠)是文本的一部分,用于指示格式的起始與結(jié)束。

    ?2?

    long@long-Ubuntu:~$ echo "UNIX" | awk ' { printf "|%-15s|/n", $1 }'

    |UNIX |

    long@long-Ubuntu:~$ echo "UNIX" | awk ' { printf "|%15s|/n", $1 }'

    | UNIX|

    ?%15s?表示占?15?個(gè)字符的字符串)


    5.?文件中的?awk?命令

    如果?awk?命令寫(xiě)在文件里,用?-f?選項(xiàng)制定?awk?的文件名,后面加上要處理的輸入文件的文件名。awk?從緩沖區(qū)讀入一條指令,接著測(cè)試?awk?文件中的每一條命令,然后對(duì)讀入的記錄執(zhí)行命令。

    ?3?

    long@long-Ubuntu:~$ cat employees

    Tom Jones 4424 5/12/66 543354

    Mary Adams 5346 11/4/63 28765

    Sally Chang 1654 7/22/54 650000

    Billy Black 1683 9/23/44 336500

    long@long-Ubuntu:~$ cat awkfile

    /^Mary/ {print "Hello Mary!"}

    {print $1, $2, $3}

    long@long-Ubuntu:~$ awk -f awkfile employees

    Tom Jones 4424

    Hello Mary!

    Mary Adams 5346

    Sally Chang 1654


    6.?記錄與字段

    ?awk?看來(lái),輸入數(shù)據(jù)具有格式和結(jié)構(gòu)。默認(rèn)情況下,每一行稱為一條記錄,以換行符結(jié)束。

    默認(rèn)情況下,輸入和輸出記錄的分隔符(行分隔符)都是回車符(換行符),分別保存在?awk?的內(nèi)置變量?ORS??RS?中,其值可以修改,只能以特定方式進(jìn)行修改。

    每條記錄的記錄號(hào)都保存在?awk?的內(nèi)置變量?NR?中,每處理完一條記錄,?NR?的值加?1?


    每條記錄由字段(?field?)組成,用空白符(空格或制表符)分隔。內(nèi)置變量?NF?保存記錄的字符數(shù)。前面提到的?FS?,用來(lái)分隔字段,并且刪除各字段前多余的空白或制表符。可以在?BEGIN?語(yǔ)句中或命令行上賦值來(lái)改變?FS?的值。也可以在命令行上通過(guò)?-F?選項(xiàng)來(lái)改變?FS?的值。

    ?4?

    long@long-Ubuntu:~$ cat employees2

    Tom Jones:4424:5/12/66:543354

    Mary Adams:5346:11/4/63:28765

    Sally Chang:1654:7/22/54:650000

    Billy Black:1683:9/23/44:336500

    long@long-Ubuntu:~$ awk -F: '/Tom Jones/{print $1,$2}' employees2

    Tom Jones 4424


    也可以使用多個(gè)字段分隔符。此時(shí)?FS?對(duì)應(yīng)的是一個(gè)正則表達(dá)式字符串,被括在方括號(hào)中。

    ?5?

    long@long-Ubuntu:~$ awk -F'[ :/t]' '{print $1,$2}' employees

    Tom Jones

    Mary Adams

    Sally Chang

    Billy Black

    long@long-Ubuntu:~$ awk -F'[ :/t]' '{print $1,$2}' employees2

    Tom Jones

    Mary Adams

    Sally Chang

    Billy Black


    前面提到的輸出字段分隔符?OFS?,輸出時(shí)如果沒(méi)有用逗號(hào)來(lái)分隔字段,結(jié)果中字段將堆在一起。OFS?的值也可以改變。


    7.?模式與操作

    模式由正則表達(dá)式、判別條件真?zhèn)蔚谋磉_(dá)式或者二者的組合構(gòu)成。?awk?默認(rèn)打印所有是表達(dá)式結(jié)果為真的文本行。模式表達(dá)式中暗含著?if?語(yǔ)句,如此,就不必用花括號(hào)將它括起來(lái)。當(dāng)?if?是顯式給出時(shí),這個(gè)表達(dá)式就成了操作語(yǔ)句,語(yǔ)法將不一樣

    操作是花括號(hào)中以分號(hào)分隔的語(yǔ)句。若操作前有模式,則該模式控制執(zhí)行操作的時(shí)機(jī)。


    正則表達(dá)式

    /?取消字符的特殊含義

    ^?在行首匹配。?^?不能用于匹配嵌套在一個(gè)字符串中的行首,?if ("line1/nLINE 2" ~ /^L/) ...?不為真。

    $?在行尾匹配。?$?不能用于匹配嵌套在一個(gè)字符串中的行尾,?if ("line1/nLINE 2" ~ /1$/) ...?不為真

    .?匹配單個(gè)任意字符,包括換行符。

    [...]?匹配制定字符組中的任意一個(gè)。

    [^ …]?匹配任何一個(gè)不在制定字符組中的字符

    |?匹配?|?兩側(cè)的任意的字符(組),在所有的正則表達(dá)式中優(yōu)先級(jí)最低。?The alternation applies to the largest possible regexps on either side.

    (...) Parentheses are used for grouping in regular expressions, as in arithmetic. They can be used to concatenate regular expressions containing the alternation operator.

    *?匹配零個(gè)或者多個(gè)前導(dǎo)字符

    +?匹配一個(gè)或者多個(gè)前導(dǎo)字符

    ??匹配零個(gè)或者多個(gè)前導(dǎo)字符

    {n} ,{n,} ,{n,m} One or two numbers inside braces denote an interval expression. If there is one number in the braces, the preceding regexp is repeated n times. If there are two numbers separated by a comma, the preceding regexp is repeated n to m times. If there is one number followed by a comma, then the preceding regexp is repeated at least n times:

    wh{3}y

    Matches ‘whhhy’, but not ‘why’ or ‘whhhhy’.

    wh{3,5}y

    Matches ‘whhhy’, ‘whhhhy’, or ‘whhhhhy’, only.

    wh{2,}y

    Matches ‘whhy’ or ‘whhhy’, and so on.


    Interval expressions were not traditionally available in awk. They were added as part of the POSIX standard to make awk and egrep consistent with each other.

    However, because old programs may use ‘{’ and ‘}’ in regexp constants, by default gawk does not match interval expressions in regexps. If either --posix or --re-interval are specified, then interval expressions are allowed in regexps.

    For new programs that use ‘{’ and ‘}’ in regexp constants, it is good practice to always escape them with a backslash. Then the regexp constants are valid and work the way you want them to.

    正則表達(dá)式中 ‘?*’,?,‘?+’?, ‘??’?以及‘?{’?和 ‘?}’?有最高的優(yōu)先級(jí),解析來(lái)是連接操作符,最后是‘?|’.算術(shù)中一樣,括號(hào)可以用來(lái)改變順序。

    ?POSIX awk??gawk?中,如果正則表達(dá)式里?'*'??'+'??'?'?前面沒(méi)有任何字符,那么這三個(gè)字符代表他們自己。很多其他版本的?awk?中,將把這視為錯(cuò)誤。

    gawk?-Specific Regexp Operators

    /Y?匹配一個(gè)單詞開(kāi)頭或者末尾的空字符串。

    /B?匹配單詞內(nèi)的空字符串。

    /<?匹配一個(gè)單詞的開(kāi)頭的空字符串,錨定開(kāi)始。

    />?匹配一個(gè)單詞的末尾的空字符串,錨定末尾。

    /w?匹配一個(gè)字母數(shù)字組成的單詞。

    /W?匹配一個(gè)非字母數(shù)字組成的單詞。

    /‘?匹配字符串開(kāi)頭的一個(gè)空字符串。

    /'?匹配字符串末尾的一個(gè)空字符串。


    The various command-line options control how?gawk?interprets characters in regexps:

    Nooptions :

    In the default case, gawk provides all the facilities of POSIX regexps and the previously described GNU regexp operators. GNU regexp operators described in Regexp Operators. However, interval expressions are not supported.

    --posix :

    Only POSIX regexps are supported; the GNU operators are not special (e.g., ‘/w’ matches a literal ‘w’). Interval expressions are allowed.

    --traditional :

    Traditional Unix awk regexps are matched. The GNU operators are not special, interval expressions are not available, nor are the POSIX character classes ([[:alnum:]], etc.). Characters described by octal and hexadecimal escape sequences are treated literally, even if they represent regexp metacharacters. Also, gawk silently skips directories named on the command line.

    --re-interval :

    Allow interval expressions in regexps, even if --traditional has been provided. (--posix automatically enables interval expressions, so --re-interval is redundant when --posix is is used.)


    POSIX?增加的括號(hào)字符類

    Class Meaning

    [:alnum:] Alphanumeric characters.

    [:alpha:] Alphabetic characters.

    [:blank:] Space and TAB characters.

    [:cntrl:] Control characters.

    [:digit:] Numeric characters.

    [:graph:] Characters that are both printable and visible.

    [:lower:] Lowercase alphabetic characters.

    [:print:] Printable characters (characters that are not control characters).

    [:punct:] Punctuation characters

    [:space:] Space characters (such as space, TAB, and formfeed, to name a few).

    [:upper:] Uppercase alphabetic characters.

    [:xdigit:] Characters that are hexadecimal digits.


    9.?范圍模板

    范圍模板匹配從第一個(gè)模板的第一次出現(xiàn)到第二個(gè)模板的第一次出現(xiàn)之間所有行。如果有一個(gè)模板沒(méi)?出現(xiàn),則匹配到開(kāi)頭或末尾。如?$ awk '/root/,/mysql/' test?將顯示?root?第一次出現(xiàn)到?mysql?一次出現(xiàn)之間的所有行。


    10.?關(guān)系運(yùn)算符

    <??<=??==??!=??>=??>??~??!~?(最后兩個(gè)表示匹配和不匹配正則表達(dá)式)


    11.?條件表達(dá)式

    條件表達(dá)式?1 ??條件表達(dá)式?2 :?條件表達(dá)式?3


    12.?算術(shù)運(yùn)算

    可以在模式中進(jìn)行計(jì)算,?awk?都將按浮點(diǎn)方式執(zhí)行運(yùn)算。支持:?+??-??*??/??%??^(冪)


    13.?邏輯操作符與復(fù)合模式

    &&??||?,!


    ?6??一個(gè)驗(yàn)證?passwd?文件有效性的例子

    long@long-Ubuntu:~$ cat /etc/passwd | awk -F: '/

    > NF != 7 {/

    > printf("line %d, does not have 7 fields:%s/n",NR,$0)}/

    > $1 !~ /[A-Za-z0-9]/{printf("line %d, non alpha and numeric user id:%d: %s/n",NR,$0)}/

    > $2 == "*" {printf("line %d, no password: %s/n", NR,$0)}'


    1 cat?把結(jié)果輸出給?awk??awk?把域之間的分隔符設(shè)為冒號(hào)。

    2?如果域的數(shù)量?(NF)?不等于?7?,就執(zhí)行下面的程序。

    3 printf?打印字符串?"line ?? does not have 7 fields"?,并顯示該條記錄。

    4?若第一個(gè)域沒(méi)包含任何字母和數(shù)字,?printf?打印“?no alpha and numeric user id"?,并顯示記錄數(shù)和記錄。

    5?如果第二個(gè)域是一個(gè)星號(hào),就打印字符串“?no passwd”?,緊跟著顯示記錄數(shù)和記錄本身。


    ?7?:幾個(gè)示例:

    $ awk '/^(no|so)/' filename-----?打印所有以模式?no??so?開(kāi)頭的行。

    $ awk '/^[ns]/{print $1}' filename-----?如果記錄以?n??s?開(kāi)頭,就打印這個(gè)記錄。

    $ awk '$1 ~/[0-9][0-9]$/(print $1}' filename-----?如果第一個(gè)域以兩個(gè)數(shù)字結(jié)束就打印這個(gè)記錄。

    $ awk '$1 == 100 || $2 < 50' filename-----?如果第一個(gè)或等于?100?或者第二個(gè)域小于?50,則打印該行。

    $ awk '$1 != 10' filename-----?如果第一個(gè)域不等于?10?就打印該行。

    $ awk '/test/{print $1 + 10}' filename-----?如果記錄包含正則表達(dá)式?test?,則第一個(gè)域加10?并打印

    $ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' filename—---?如果第一個(gè)域大于?5?則打印問(wèn)號(hào)后面?的表達(dá)式值,否則打印冒號(hào)后面的表達(dá)式值。

    $ awk '/^root/,/^mysql/' filename----?打印從以正則表達(dá)式?root?開(kāi)頭的記錄到以正則表達(dá)式?mysql?開(kāi)頭?的記錄范圍內(nèi)的所有記錄。如果找到一個(gè)新的正則表達(dá)式?root?開(kāi)頭的記錄,則繼續(xù)打印直到下一個(gè)以正則?表達(dá)式?mysql?開(kāi)頭的記錄為止,或到文件末尾。


    14.?變量

    ?awk?中,變量不需要定義就可以直接使用,變量類型可以是數(shù)字或字符串,由?awk?根據(jù)上下文推導(dǎo),不用指定

    變量名可以包括字母、數(shù)字和下劃線,但不能以數(shù)字開(kāi)頭。

    賦值格式:?Variable = expression

    變量被設(shè)置后,就變成與等號(hào)右邊那個(gè)表達(dá)式相同的類型。

    未經(jīng)初始化的變量的值是?0?或者“”,具體是哪個(gè)取決于它們被使用時(shí)的上下文。

    將一個(gè)字符串強(qiáng)制轉(zhuǎn)換為數(shù)字,方法為:?name+0

    將數(shù)字轉(zhuǎn)換成字符串的方法是:?number “”

    賦值運(yùn)算符:?=??+=??-=??*=??/=??%=??^=

    遞增遞減運(yùn)算符,也分為前置和后置兩種,遵循的規(guī)則與?C?語(yǔ)言中一樣


    awk?可以在命令行中給變量賦值,然后將這個(gè)變量傳輸給?awk?腳本。如?$ awk -F: -f awkscript month=4 year=2004 filename?,上式的?month??year?都是自定義變量,分別被賦值為?4?2004?。在?awk?腳本中,這些變量使用起來(lái)就象是在腳本中建立的一樣。注意,如果命令行中filename?的位置在變量之前,那么在?BEGIN?語(yǔ)句中的變量就不能被使用(參見(jiàn)后面的?BEGIN?模式)。

    -v?選項(xiàng),?awk??-v?選項(xiàng)允許在?BEGIN?語(yǔ)句中,處理命令行變量。從命令行傳遞的每一個(gè)變量前面都必須加?-v?選項(xiàng)


    字段變量也可被賦值和修改。新的字段可以通過(guò)賦值來(lái)創(chuàng)建。字段變量引用的字段如果沒(méi)有值,則被賦值為空串(即如果只有?4?個(gè)字段,但是對(duì)?$6?復(fù)制,那么不存在的?$5?被賦值為空串)。字段的值發(fā)生變化時(shí),?awk?會(huì)以?OFS?的值作為字段間隔符重新計(jì)算?$0?的值。字段數(shù)目通常在?100?以內(nèi)。如?$ awk '{$2 = 100 + $1; print }' test,?上式表示,如果第二個(gè)域不存在,?awk?將計(jì)算表達(dá)式100??$1?的值,并將其賦值給?$2?,如果第二個(gè)域存在,則用表達(dá)式的值覆蓋?$2?原來(lái)的值。


    內(nèi)建變量

    $n?當(dāng)前記錄的第?n?個(gè)字段,字段間由?FS?分隔。

    $0?完整的輸入記錄。

    ARGC?命令行參數(shù)的數(shù)目。

    ARGIND?命令行中當(dāng)前文件的位置?(??0?開(kāi)始算?)?

    ARGV?包含命令行參數(shù)的數(shù)組。

    CONVFMT?數(shù)字轉(zhuǎn)換格式?(?默認(rèn)值為?%.6g)

    ENVIRON?環(huán)境變量關(guān)聯(lián)數(shù)組。

    ERRNO?最后一個(gè)系統(tǒng)錯(cuò)誤的描述。

    FIELDWIDTHS?字段寬度列表?(?用空格鍵分隔?)?

    FILENAME?當(dāng)前文件名。

    FNR??NR?,但相對(duì)于當(dāng)前文件。

    FS?字段分隔符?(?默認(rèn)是任何空格?)?

    IGNORECASE?如果為真(即非?0?值),則進(jìn)行忽略大小寫(xiě)的匹配。

    NF?當(dāng)前記錄中的字段數(shù)。

    NR?當(dāng)前記錄數(shù)。

    OFMT?數(shù)字的輸出格式?(?默認(rèn)值是?%.6g)?

    OFS?輸出字段分隔符?(?默認(rèn)值是一個(gè)空格?)?

    ORS?輸出記錄分隔符?(?默認(rèn)值是一個(gè)換行符?)?

    RLENGTH??match?函數(shù)所匹配的字符串的長(zhǎng)度。

    RS?記錄分隔符?(?默認(rèn)是一個(gè)換行符?)?

    RSTART??match?函數(shù)所匹配的字符串的第一個(gè)位置。

    SUBSEP?數(shù)組下標(biāo)分隔符?(?默認(rèn)值是?/034)?


    15.?BEGIN?模式

    BEGIN?模式后面跟一個(gè)操作塊。?awk?必須在對(duì)輸入文件進(jìn)行任何處理之前,先執(zhí)行該操作塊。常被用于修改內(nèi)置變量的值,為用戶自定義變量賦初值和打印輸出的頁(yè)眉或者標(biāo)題。。

    ?8?

    $ awk 'BEGIN{FS=":"; OFS="/t"; ORS="/n/n"}{print $1,$2,$3} filename?。上式表示,在?處理輸入?文件以前,域分隔符?(FS)?被設(shè)為冒號(hào),輸出文件分隔符?(OFS)?被設(shè)置為制表符,輸出記錄分隔符?(ORS)?被設(shè)?置為兩個(gè)換行符。?$ awk 'BEGIN{print "TITLE TEST"}?只打印標(biāo)題。


    編寫(xiě)?awk?腳本時(shí),可以先測(cè)試好?BEGIN?塊操作,再寫(xiě)程序的其他部分。


    16.?END?模式

    END?模式不匹配任何輸入行,而是執(zhí)行任何與之關(guān)聯(lián)的操作。?Awk?處理完所有輸入行之后才處理END?模式。

    ?9?

    $ awk 'END{print "The number of records is" NR}' test?,上式將打印所有被處理的記錄數(shù)。


    17.?重定向和管道

    awk?可使用?shell?的重定向符進(jìn)行重定向輸出

    輸入重定向需用到?getline?函數(shù)。?getline?從標(biāo)準(zhǔn)輸入、管道或者當(dāng)前正在處理的文件之外的其他輸入文件獲得輸入。它負(fù)責(zé)從輸入獲得下一行的內(nèi)容,并給?NF,NR??FNR?等內(nèi)建變量賦值。如果得到一條記錄,?getline?函數(shù)返回?1?,如果到達(dá)文件的末尾就返回?0?,如果出現(xiàn)錯(cuò)誤,例如打開(kāi)文件失敗,就返回?-1?

    ?10?

    $ awk 'BEGIN{ "date" | getline d; print d}' filename

    執(zhí)行?linux??date?命令,并通過(guò)管道輸出給?getline?,然后再把輸出賦值給自定義變量?d?,并打印它。

    $ awk 'BEGIN{"date" | getline d; split(d,mon); print mon[2]}' filename

    執(zhí)行?shell??date?命令,并通過(guò)管道輸出給?getline?,然后?getline?從管道中讀取并將輸入賦值給d??split??數(shù)把變量?d?轉(zhuǎn)化成數(shù)組?mon?,然后打印數(shù)組?mon?的第二個(gè)元素。

    $ awk 'BEGIN{while( "ls" | getline) print}'

    命令?ls?的輸出傳遞給?getline?作為輸入,循環(huán)使?getline??ls?的輸出中讀取一行,并把它打印到屏幕。這里沒(méi)有?輸入文件,因?yàn)?BEGIN?塊在打開(kāi)輸入文件前執(zhí)行,所以可以忽略輸入文件。

    $ awk 'BEGIN{while (getline < "/etc/passwd" > 0) lc++; print lc}'

    awk?將逐行讀取文件?/etc/passwd?的內(nèi)容,在到達(dá)文件末尾前,計(jì)數(shù)器?lc?一直增加,當(dāng)?shù)侥┪矔r(shí),打印?lc?的值。?注意,如果文件不存在,?getline?返回?-1?,如果到達(dá)文件的末尾就返回?0?,如果讀到一行,就返回?1?,所以命令?while (getline < "/etc/passwd")?在文件不存在的情況下將陷入無(wú)限循環(huán),因?yàn)榉祷?/span>?-1?表示邏輯真。


    如果在?awk?程序中打開(kāi)了管道?,就必須先關(guān)閉它才能打開(kāi)另一個(gè)管道。管道符右邊的命令被括在雙引號(hào)之間。每次只能打開(kāi)一個(gè)管道。如果打算再次在?awk?程序中使用某個(gè)文件或管道進(jìn)行讀寫(xiě),則可能要先關(guān)閉程序,因?yàn)槠渲械墓艿罆?huì)保持打開(kāi)狀態(tài)直至腳本運(yùn)行結(jié)束。注意:管道一旦被打開(kāi),就會(huì)保持打開(kāi)狀態(tài)直至?awk?退出。?END?塊中的語(yǔ)句也會(huì)受到管道影響。通過(guò)?close()?可關(guān)閉管道

    ?11?

    (腳本)

    { print $1,$2,$3 | “sort -r +1 -2 +0 -1” }

    END{

    close(“sort -r +1 -2 +0 -1”)

    <rest of statements> }


    awk?內(nèi)置函數(shù)?system??Linux?系統(tǒng)命令作為參數(shù),執(zhí)行該命令并將命令的退出狀態(tài)返回給?awk?程序。作為參數(shù)的命令必須加雙引號(hào)。


    18.?條件語(yǔ)句

    awk?條件語(yǔ)句源于?C?語(yǔ)言,可以用他們對(duì)包含判斷語(yǔ)句的程序進(jìn)行控制。

    if?語(yǔ)句

    格式?: {if (expression){

    statement; statement; ...

    }

    }

    ?12?

    $ awk '{if ($1 <$2) print $2 "too high"}' test

    如果第一個(gè)域小于第二個(gè)域則打印。

    $ awk '{if ($1 < $2) {count++; print "ok"}}' test

    如果第一個(gè)域小于第二個(gè)域,則?count??1?,并打印?ok?


    if/else?語(yǔ)句

    格式:?{if (expression){

    statement; statement; ...

    }

    else{

    statement; statement; ...

    }

    }

    ?13?

    $ awk '{if ($1 > 100) print $1 "bad" ; else print "ok"}' test

    如果?$1??100?則打印?$1 bad,?否則打印?ok?

    $ awk '{if ($1 > 100){ count++; print $1} else {count--; print $2}' test

    如果?$1?大于?100?,則?count?加一,并打印?$1?,否則?count?減一,并打印?$1?


    if/else else if?語(yǔ)句

    格式:?{if (expression){

    statement; statement; ...

    }

    else if (expression){

    statement; statement; ...

    }

    else if (expression){

    statement; statement; ...

    }

    else {

    statement; statement; ...

    }

    }


    19.?循環(huán)語(yǔ)句

    常常用來(lái)對(duì)記錄中的每個(gè)字段重復(fù)執(zhí)行某些操作?,或者在?END?塊中用來(lái)循環(huán)處理某個(gè)數(shù)組中的所有元素。三種類型的循環(huán):?while?循環(huán),?for?循環(huán),特殊?for?循環(huán)

    while?循環(huán)

    第一步給一個(gè)變量賦初值,在?while?中測(cè)試該變量,若值為真(非?0?),則進(jìn)入循環(huán)執(zhí)行語(yǔ)句。do while?循環(huán)與?while?類似,唯一的區(qū)別是?do while?至少執(zhí)行一次循環(huán)體,然后才測(cè)試表達(dá)式。

    ?14?

    $ awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' test

    變量的初始值為?1?,若?i?小于可等于?NF(?記錄中域的個(gè)數(shù)?),?則執(zhí)行打印語(yǔ)句,且?i?增加?1?。直到?i的值大于?NF.


    for?循環(huán)

    for?循環(huán)的圓括號(hào)中需要?3?個(gè)表達(dá)式,前兩個(gè)分別是初始化和測(cè)試表達(dá)式,第?3?個(gè)用于更新測(cè)試表達(dá)式所用的變量。注意,?for?循環(huán)中,第一條語(yǔ)句只能初始化一個(gè)變量(這與?C?語(yǔ)言不同)

    ?15?

    $ awk '{for (i = 1; i<NF; i++) print NF,$i}' test?。作用同上。


    循環(huán)控制

    break?語(yǔ)句用于在滿足條件的情況下跳出循環(huán)

    continue?語(yǔ)句用于在滿足條件的情況下忽略后面的語(yǔ)句,直接返回循環(huán)的頂端。

    ?16?

    1. {for ( x=3; x<=NF; x++)

    if ($x<0){print "Bottomed out!"; break}}

    2. {for ( x=3; x<=NF; x++)

    if ($x==0){print "Get next item"; continue}}


    20.?程序控制語(yǔ)句

    next?語(yǔ)句,從輸入文件中取出下一行輸入,然后從?awk?腳本的頂部重新開(kāi)始執(zhí)行。

    exit?語(yǔ)句,用于終止?awk?程序。它只能中斷對(duì)記錄的處理,不能跳過(guò)?END?語(yǔ)句。若?exit?語(yǔ)句的參數(shù)是一個(gè)?0~255?之間的值,這個(gè)值會(huì)被打印在命令行上,以表明程序是否執(zhí)行成功?,并指出失敗類型。


    21.?數(shù)組

    數(shù)組在?awk?中被稱為關(guān)聯(lián)數(shù)組??associative arrays?),其下表既可以是字符串也可以是數(shù)字。數(shù)組的鍵和值都存儲(chǔ)在?awk?程序內(nèi)部的一個(gè)表中,該表采用的是?散列算法,所以數(shù)組元素不是順序存儲(chǔ)的。數(shù)組也是被用到時(shí)才被創(chuàng)建。?awk?還能判定數(shù)組用于保存數(shù)字還是字符串,根據(jù)上下文被初始化為?0?或者空字符串。數(shù)組大小不需要聲明。

    用變量作為數(shù)組下標(biāo)。

    ?17?

    $ awk {name[x++]=$2};END{for(i=0;i<NR;i++) print i,name[i]}' test

    數(shù)組?name?中的下標(biāo)是一個(gè)自定義變量?x??awk?初始化?x?的值為?0?,在每次使用后增加?1?。第二個(gè)域的值被賦給?name?數(shù)組的各個(gè)元素。在?END?模塊中,?for?循環(huán)被用于循環(huán)整個(gè)數(shù)組,從下標(biāo)為?0?的元素開(kāi)始,打印那些存儲(chǔ)在數(shù)組中的值。因?yàn)橄聵?biāo)是關(guān)健字,所以它不一定從?0?開(kāi)始,可以從任何值開(kāi)始。


    特殊?for?循環(huán)

    當(dāng)下標(biāo)為字符串或者非連續(xù)的數(shù)字時(shí),不能用?for?循環(huán)來(lái)遍歷數(shù)組。這是就要使用特殊的?for?循環(huán)。

    格式:??for??item in arrayname) {

    print arrayname[item]

    }

    }


    用字符串作為數(shù)組下標(biāo)

    數(shù)組下表可以由包含單個(gè)字符或字符串的變量組成,如果是字符串,就必須用雙引號(hào)括起來(lái)。


    用字段的值作為數(shù)組下標(biāo)

    ?18?

    long@long-Ubuntu:~$ cat datafile1

    4234 Tom 43

    4567 Arch 45

    2008 Eliza 65

    4571 Tom 22

    3298 Eliza 21

    4622 Tom 53

    2345 Mary 24

    long@long-Ubuntu:~$ awk '{count[$2]++}END{for(name in count)print name, / count[name]}' dataf ile1

    Arch 1

    Tom 3

    Eliza 2

    Mary 1

    統(tǒng)計(jì)文件中某個(gè)字段出現(xiàn)的次數(shù)


    數(shù)組與函數(shù)

    awk?的內(nèi)置函數(shù)?split?能夠?qū)⒆址鸱譃?/span>?詞,然后保存在數(shù)組中。

    格式:?split?(字符串,數(shù)組,字段分隔符)

    split?(字符串,數(shù)組)

    awk?的內(nèi)置函數(shù)?delete?用于刪除數(shù)組元素


    多維數(shù)組

    awk?定義多為數(shù)組?的方法是把多個(gè)下標(biāo)串成字符串,下標(biāo)之間用內(nèi)置變量?SUBSEP?的值分隔。變量?SUBSEP?的值默認(rèn)為“?/034”?,這是個(gè)不可打印的字符,不太可能用作下標(biāo)中的字符。

    ?19?

    long@long-Ubuntu:~$ cat datafile2

    1 2 3 4 5

    2 3 4 5 6

    3 4 5 6 7

    6 7 8 9 10

    long@long-Ubuntu:~$ awk '{nf=NF

    for(x=1; x<=NF; x++){

    matrix[NR,x] = $x

    }

    }END{

    for(x=1;x<=NR;x++){

    for(y=1;y<=nf;y++)

    printf "%d/t", matrix[x,y]

    printf "/n"

    }

    }' datafile2

    1 2 3 4 5

    2 3 4 5 6

    3 4 5 6 7

    6 7 8 9 10


    22.?處理命令行參數(shù)

    awk?可以從內(nèi)置數(shù)組?ARGV?中得到命令行參數(shù),其中包括命令?awk?。但所有傳遞給?awk?的選項(xiàng)不再其中。?ARGV?數(shù)組下標(biāo)從?0?開(kāi)始。?ARGC?是一個(gè)包含命令行參數(shù)個(gè)數(shù)的內(nèi)置變量。


    23.awk?的內(nèi)置函數(shù)

    字符串函數(shù)

    sub?函數(shù)匹配記錄中最大、最靠左邊的子字符串的正則表達(dá)式,并用替換字符串替換這些字符串。如果沒(méi)有指定目標(biāo)字符串就默認(rèn)使用整個(gè)記錄。替換只發(fā)生在第一次匹配的時(shí)候。

    格式:?sub (regular expression, substitution string):

    sub (regular expression, substitution string, target string)

    ?20?

    $ awk '{ sub(/test/, "mytest"); print }' testfile

    $ awk '{ sub(/test/, "mytest"); $1}; print }' testfile

    第一個(gè)例子在整個(gè)記錄中匹配,替換只發(fā)生在第一次匹配發(fā)生的時(shí)候

    第二個(gè)例子在整個(gè)記錄的第一個(gè)域中進(jìn)行匹配,替換只發(fā)生在第一次匹配發(fā)生的時(shí)候。

    gsub?函數(shù)作用如?sub?,但它在整個(gè)文檔中進(jìn)行匹配。

    格式:?gsub (regular expression, substitution string)

    gsub (regular expression, substitution string, target string)


    index?函數(shù)返回子字符串第一次被匹配的位置,偏移量從位置?1?開(kāi)始。

    格式:?index(string, substring)


    length?函數(shù)返回記錄的字符數(shù),若未指定參數(shù),則?length?函數(shù)返回記錄中的字符個(gè)數(shù)

    格式:?length( string )

    length


    substr?函數(shù)返回從字符串指定位置開(kāi)始的子字符串,如果指定長(zhǎng)度超過(guò)實(shí)際長(zhǎng)度,就返回其實(shí)際內(nèi)容。

    格式:?substr( string, starting position )

    substr( string, starting position,?子串長(zhǎng)度?)


    match?函數(shù)返回在字符串中正則表達(dá)式位置的索引,如果找不到指定的正則表達(dá)式則返回?0?match?函數(shù)把內(nèi)置變量?RSTART?設(shè)為子串在字符串中的起始位置,?RLENGTH?為則設(shè)為子串的長(zhǎng)度。這些變量可以被?substr?函數(shù)用來(lái)提取相應(yīng)模式的子串。

    格式:?match( string, regular expression )

    ?21?

    $ awk '{start=match("this is a test",/[a-z]+$/); print start}' filename

    $ awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'/ filename

    第一個(gè)實(shí)例打印以連續(xù)小寫(xiě)字符結(jié)尾的開(kāi)始位置,這里是?11?

    第二個(gè)實(shí)例還打印?RSTART??RLENGTH?變量,這里是?11(start)??11(RSTART)?4(RLENGTH)?


    toupper??tolower?函數(shù)可用于字符串大小間的轉(zhuǎn)換,該功能只在?gawk?中有效。

    格式:?toupper( string )

    tolower( string )


    split?函數(shù)可按給定的分隔符把字符串分割為一個(gè)數(shù)組。如果分隔符沒(méi)提供,則按當(dāng)前?FS?值進(jìn)行分割。

    格式:?split( string, array, field separator )

    split( string, array )

    ?22?

    $ awk '{ split( "20:18:00", time, ":" ); print time[2] }' filename

    把時(shí)間按冒號(hào)分割到?time?數(shù)組內(nèi),并顯示第二個(gè)數(shù)組元素?18?


    sprintf?函數(shù)?返回一個(gè)指定格式的表達(dá)式。可以在?sprintf?函數(shù)中使用?printf?函數(shù)的格式規(guī)范

    格式:?variable=sprintf(“?含有格式說(shuō)明的字符串”?,?表達(dá)式?1,?表達(dá)式?2??..,?表達(dá)式?n)



    內(nèi)置算術(shù)函數(shù)

    int(x)

    returns nearest integer to x, located between x and zero and truncated toward zero.

    sqrt(x)

    returns the positive square root of x. gawk reports an error if x is negative.

    exp(x)

    returns the exponential of x (e ^ x) or reports an error if x is out of range.

    log(x)

    returns the natural logarithm of x, if x is positive; otherwise, it reports an error.

    sin(x)

    returns the sine of x, with x in radians.

    cos(x)

    returns the cosine of x, with x in radians.

    atan2(y, x)

    returns the arctangent of y / x in radians.

    rand()

    returns a random number??uniformly distributed between zero and one??0<=value<1

    srand??x)

    function?srand?sets the seed, for generating random numbers to the value x


    時(shí)間函數(shù)

    systime?函數(shù)返回從?1970??1??1?日開(kāi)始到當(dāng)前時(shí)間?(?不計(jì)閏年?)?的整秒數(shù)。

    格式:?systime()


    strftime?函數(shù)使用?C?庫(kù)中的?strftime?函數(shù)格式化時(shí)間。

    日期和時(shí)間格式說(shuō)明符

    格式?描述

    %a 星期幾的縮寫(xiě)?(Sun)

    %A 星期幾的完整寫(xiě)法?(Sunday)

    %b 月名的縮寫(xiě)?(Oct)

    %B 月名的完整寫(xiě)法?(October)

    %c 本地日期和時(shí)間

    %d 十進(jìn)制日期

    %D 日期?08/20/99

    %e 日期,如果只有一位會(huì)補(bǔ)上一個(gè)空格

    %H 用十進(jìn)制表示?24?小時(shí)格式的小時(shí)

    %I 用十進(jìn)制表示?12?小時(shí)格式的小時(shí)

    %j ?1??1?日起一年中的第幾天

    %m 十進(jìn)制表示的月份

    %M 十進(jìn)制表示的分鐘

    %p 12?小時(shí)表示法?(AM/PM)

    %S 十進(jìn)制表示的秒

    %U 十進(jìn)制表示的一年中的第幾個(gè)星期?(?星期天作為一個(gè)星期的開(kāi)始?)

    %w 十進(jìn)制表示的星期幾?(?星期天是?0)

    %W 十進(jìn)制表示的一年中的第幾個(gè)星期?(?星期一作為一個(gè)星期的開(kāi)始?)

    %x 重新設(shè)置本地日期?(08/20/99)

    %X 重新設(shè)置本地時(shí)間?(12??00??00)

    %y 兩位數(shù)字表示的年?(99)

    %Y 當(dāng)前月份

    %Z 時(shí)區(qū)?(PDT)

    %% 百分號(hào)?(%)

    格式:?strftime( [format specification][,timestamp] )


    24.?用戶自定義函數(shù)

    腳本中凡是可以出現(xiàn)模式操作規(guī)則的位置都可以放置用戶自定義的函數(shù)。

    格式:?函數(shù)名?(?參數(shù)?,?參數(shù)?,?參數(shù)?, ...){

    語(yǔ)句

    return?表達(dá)式

    (?注:?return?語(yǔ)句和表達(dá)式都是可選項(xiàng)?)

    }

    變量以參數(shù)值的方式傳遞,且僅在使用它的函數(shù)中局部有效。函數(shù)使用的只是變量的副本。數(shù)組則通過(guò)地址或引用被傳 遞,因此,可以在函數(shù)中直接修改數(shù)組的元素。函數(shù)中的變量只要不是從參數(shù)列表傳來(lái)的,都視為全局變量。調(diào)用函數(shù)時(shí),如果沒(méi)有指定某個(gè)形參的值,該參數(shù)被初 始化為空。

    ?23?

    long@long-Ubuntu:~$ cat grades

    44 55 66 22 77 99

    100 22 77 99 33 66

    55 66 100 99 88 45

    long@long-Ubuntu:~$ cat sorter.sc

    #Scriptname: sorter

    #It sorts numbers in ascending order

    function sort(scores, num_elements, temp, i, j){

    #temp,i,j will be local and private

    #with an initial value of null

    for(i=2; i<=num_elements; ++i){

    for(j=i; scores[j-1]>scores[j]; --j){

    temp = scores[j]

    scores[j] = scores[j-1]

    scores[j-1] = temp

    }

    }

    }

    {for (i=1; i<=NF; i++)

    grades[i] = $i

    ?

    sort(grades,NF)

    for(j=1;j<NF;++j)

    printf("%d ", grades[j])

    printf("/n")

    }

    long@long-Ubuntu:~$ awk -f sorter.sc grades

    22 44 55 66 77

    22 33 66 77 99

    45 55 66 88 99


    25.?雜項(xiàng)

    固定字段

    有些數(shù)據(jù)沒(méi)有明顯的字段分隔符,卻有固定寬度的列。預(yù)處理這些數(shù)據(jù)時(shí),?substr?很有用

    空字段

    用固定長(zhǎng)度的字段來(lái)存儲(chǔ)數(shù)據(jù),就可能出現(xiàn)一些空字段,?substr?可以被用來(lái)保存字段,而不考慮它們是否包含數(shù)據(jù)



    26.awk?命令選項(xiàng)

    -F fs or --field-separator fs

    指定輸入文件折分隔符,?fs?是一個(gè)字符串或者是一個(gè)正則表達(dá)式,如?-F:?

    -v var=value or --asign var=value

    賦值一個(gè)用戶定義變量。

    -f scripfile or --file scriptfile

    從腳本文件中讀取?awk?命令。

    -mf nnn and -mr nnn

    對(duì)?nnn?值設(shè)置內(nèi)在限制,?-mf?選項(xiàng)限制分配給?nnn?的最大塊數(shù)目;?-mr?選項(xiàng)限制記錄的最大數(shù)目。這兩個(gè)功能是?Bell?實(shí)驗(yàn)室版?awk?的擴(kuò)展功能,在標(biāo)準(zhǔn)?awk?中不適用。

    -W compact or --compat, -W traditional or --traditional

    在兼容模式下運(yùn)行?awk?。所以?gawk?的行為和標(biāo)準(zhǔn)的?awk?完全一樣,所有的?awk?擴(kuò)展都被忽略。

    -W copyleft or --copyleft, -W copyright or --copyright

    打印簡(jiǎn)短的版權(quán)信息。

    -W help or --help, -W usage or --usage

    打印全部?awk?選項(xiàng)和每個(gè)選項(xiàng)的簡(jiǎn)短說(shuō)明。

    -W lint or --lint

    打印不能向傳統(tǒng)?unix?平臺(tái)移植的結(jié)構(gòu)的警告。

    -W lint-old or --lint-old

    打印關(guān)于不能向傳統(tǒng)?unix?平臺(tái)移植的結(jié)構(gòu)的警告。

    -W posix

    打開(kāi)兼容模式。但有以下限制,不識(shí)別:?/x?、函數(shù)關(guān)鍵字、?func?、換碼序列以及當(dāng)?fs?是一個(gè)空格時(shí),將新行作為一個(gè)域分隔符;操作符?**??**=?不能代替?^??^=??fflush?無(wú)效。

    -W re-interval or --re-inerval

    允許間隔正則表達(dá)式的使用,參考?(grep?中的?Posix?字符類?)?,如括號(hào)表達(dá)式?[[:alpha:]]?

    -W source program-text or --source program-text

    使用?program-text?作為源代碼,可與?-f?命令混用。

    -W version or --version

    打印?bug?報(bào)告信息的版本。

    ?

    http://blog.csdn.net/longwen7/article/details/6336757

    總結(jié)

    以上是生活随笔為你收集整理的AWK介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。