flymeteor@Blog



AWK学习

AWK 是什么?

最简�地说, AWK 是一�用于处�文本的编程语言工具。 AWK 实用工具的语言在很多方�类似于 shell
编程语言,尽管 AWK 具有完全属于其本身的语法。在最�创造 AWK
时,其目的是用于文本处ç?†ï¼Œå¹¶ä¸”è¿™ç§?语言的基础是,å?ªè¦?在输入数æ?®ä¸­æœ‰æ¨¡å¼?匹é…?,就执行一系列指令。该实用工具扫æ??文件中的æ¯?一行,查找与命令行中所给定
内容相匹�的模�。如果�现匹�内容,则进行下一个编程步骤。如果找�到匹�内容,则继续处�下一行。

尽管�作�能会很��,但命令的语法始终是:

awk ‘{pattern + action}’ {filenames}

其中 pattern 表示 AWK 在数�中查找的内容,而 action 是在找到匹�内容时所执行的一系列命令。花括� ({}) �需�在程�中始终出现,但它们用于根�特定的模�对一系列指令进行分组。

了解字段

实用工具将�个输入行分为记录和字段。 记录 是�行的输入,而��记录包�若干字段。默认的字段分隔符是空格或制表符,而记录的分隔符是�行。虽然在默认情况下将制表符和空格都看作字段分隔符(多个空格�然作为一个分隔符),但是�以将分隔符从空格改为任何其它字符。

为了进行演示,请查看以下�存为 emp_names 的员工列表文件:

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

46017 FELDMAN EVAN MOBILE AL

46018 SWIM STEVE UNKNOWN AL

46019 BOGUE ROBERT PHOENIX AZ

46021 JUNE MICAH PHOENIX AZ

46022 KANE SHERYL UNKNOWN AR

46024 WOOD WILLIAM MUNCIE IN

46026 FERGUS SARAH MUNCIE IN

46027 BUCK SARAH MUNCIE IN

46029 TUTTLE BOB MUNCIE IN

当 AWK 读�输入内容时,整�记录被分�给�� $0 。�个字段以字段分隔符分开,被分�给�� $1 � $2 � $3 等等。一行在本质上�以包�无数个字段,通过字段��访问�个字段。因此,命令

awk ‘{print $1,$2,$3,$4,$5}’ names

将会产生的打�输出是

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

46017 FELDMAN EVAN MOBILE AL

46018 SWIM STEVE UNKNOWN AL

46019 BOGUE ROBERT PHOENIX AZ

46021 JUNE MICAH PHOENIX AZ

46022 KANE SHERYL UNKNOWN AR

46024 WOOD WILLIAM MUNCIE IN

46026 FERGUS SARAH MUNCIE IN

46027 BUCK SARAH MUNCIE IN

46029 TUTTLE BOB MUNCIE IN

值得注æ„?的一项é‡?è¦?内容是, AWK 解释由空格分隔的五个字段,但当它打å?°æ˜¾ç¤ºå†…容时,在æ¯?个字段间å?ªæœ‰ä¸€ä¸ªç©ºæ ¼ã€‚利用为æ¯?个字段指定了唯一å?·ç ?的功能,您å?¯ä»¥é€‰æ‹©å?ªæ‰“å?°ç‰¹å®šçš„字段。例如,å?ªæ‰“å?°æ¯?æ?¡è®°å½•的姓å??时,å?ªéœ€é€‰æ‹©ç¬¬äºŒä¸ªå’Œç¬¬ä¸‰ä¸ªå­—段进行打å?°ï¼š

$ awk ‘{print $2,$3}’ emp_names

DULANEY EVAN

DURHAM JEFF

STEEN BILL

FELDMAN EVAN

SWIM STEVE

BOGUE ROBERT

JUNE MICAH

KANE SHERYL

WOOD WILLIAM

FERGUS SARAH

BUCK SARAH

TUTTLE BOB

$

您还å?¯ä»¥æŒ‡å®šæŒ‰ä»»ä½•顺åº?打å?°å­—段,而无论它们在记录中是如何存在的。因此,å?ªéœ€è¦?显示姓å??字段,并且使其顺åº?颠倒,先显示å??å­—å†?显示姓æ°?:

$ awk ‘{print $3,$2}’ emp_names

EVAN DULANEY

JEFF DURHAM

BILL STEEN

EVAN FELDMAN

STEVE SWIM

ROBERT BOGUE

MICAH JUNE

SHERYL KANE

WILLIAM WOOD

SARAH FERGUS

SARAH BUCK

BOB TUTTLE

$

使用模�

通过包�一个必须匹�的模�,您�以选择�对特定的记录而�是所有的记录进行�作。模�匹�的最简�形�是�索,其中�匹�的项目被包�在斜线 ( /pattern/ ) 中。例如,�对那些居�在阿拉巴马州的员工执行��的�作:

$ awk ‘/AL/ {print $3,$2}’ emp_names

EVAN DULANEY

JEFF DURHAM

BILL STEEN

EVAN FELDMAN

STEVE SWIM

$

如果您�指定�打�的字段,则会打�整个匹�的�目:

$ awk ‘/AL/’ emp_names

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

46017 FELDMAN EVAN MOBILE AL

46018 SWIM STEVE UNKNOWN AL

$

对å?Œä¸€æ•°æ?®é›†çš„多个命令å?¯ä»¥ç”¨åˆ†å?· ( ; ) 分隔开。例如,在一行中打å?°å§“å??,而在å?¦ä¸€è¡Œä¸­æ‰“å?°åŸŽå¸‚和州å??:

$ awk ‘/AL/ {print $3,$2 ; print $4,$5}’ emp_names

EVAN DULANEY

MOBILE AL

JEFF DURHAM

MOBILE AL

BILL STEEN

MOBILE AL

EVAN FELDMAN

MOBILE AL

STEVE SWIM

UNKNOWN AL

$

如果没有使用分� ( print $3,$2,$4,$5 ) ,则会在�一行中显示所有内容。�一方�,如果分别给出两个打�语�,则会产生完全��的结果:

$ awk ‘/AL/ {print $3,$2} {print $4,$5}’ emp_names

EVAN DULANEY

MOBILE AL

JEFF DURHAM

MOBILE AL

BILL STEEN

MOBILE AL

EVAN FELDMAN

MOBILE AL

STEVE SWIM

UNKNOWN AL

PHOENIX AZ

PHOENIX AZ

UNKNOWN AR

MUNCIE IN

MUNCIE IN

MUNCIE IN

MUNCIE IN

$

�有在列表中找到 AL 时�会给出字段三和字段二。但是,字段四和字段五是无�件的,始终打�它们。�有第一组花括�中的命令对��紧邻的命令 ( /AL/ ) 起作用。

结果�常�便于阅读,�以使其�微更清晰一些。首先,在城市与州之间�入一个空格和逗�。然�,在�两行显示之�放置一个空行:

$ awk ‘/AL/ {print $3,$2 ; print $4″, “$5″\n”}’ emp_names

EVAN DULANEY

MOBILE , AL

JEFF DURHAM

MOBILE , AL

 

BILL STEEN

MOBILE , AL

 

EVAN FELDMAN

MOBILE , AL

 

STEVE SWIM

UNKNOWN, AL

$

在第四和第五个字段之间,添加一个逗�和一个空格(在引�之间),在第五个字段��,打�一个�行符 ( \n ) 。在 AWK 打�语�中还�以使用那些�在 echo 命令中使用的所有特殊字符,包括:

  • \n (æ?¢è¡Œï¼‰
  • \t (制表)
  • \b (退格)
  • \f (进纸)
  • \r (回车)

因此,�读�全部五个最�由制表符分隔开的字段,并且也利用制表符打�它们,您�以编程如下

$ awk ‘{print $1″\t”$2″\t”$3″\t”$4″\t”$5}’ emp_names

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

46017 FELDMAN EVAN MOBILE AL

46018 SWIM STEVE UNKNOWN AL

46019 BOGUE ROBERT PHOENIX AZ

46021 JUNE MICAH PHOENIX AZ

46022 KANE SHERYL UNKNOWN AR

46024 WOOD WILLIAM MUNCIE IN

46026 FERGUS SARAH MUNCIE IN

46027 BUCK SARAH MUNCIE IN

46029 TUTTLE BOB MUNCIE IN

$

通过连续设置多项标准并用管� ( | ) 符�将其分隔开,您�以一次�索多个模�匹�:

$ awk ‘/AL|IN/’ emp_names

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

46017 FELDMAN EVAN MOBILE AL

46018 SWIM STEVE UNKNOWN AL

46024 WOOD WILLIAM MUNCIE IN

46026 FERGUS SARAH MUNCIE IN

46027 BUCK SARAH MUNCIE IN

46029 TUTTLE BOB MUNCIE IN

$

这样�找到�个阿拉巴马州和�第安那州居民的匹�记录。但是在试图找出居�在亚利桑那州的人时,出现了一个问题:

$ awk ‘/AR/’ emp_names

46019 BOGUE ROBERT PHOENIX AZ

46021 JUNE MICAH PHOENIX AZ

46022 KANE SHERYL UNKNOWN AZ

46026 FERGUS SARAH MUNCIE IN

46027 BUCK SARAH MUNCIE IN

$

员工 46026 å’Œ 46027 没有ä½?在亚利桑那州;但是他们的å??字中包å?«æ‰€æ?œç´¢çš„字符åº?列。切记,当在 AWK
中进行模�匹�时,例如 grep � sed 或者大部分其他 Linux/Unix
命令,将在记录(行)中的任何�置查找匹�,除�指定进行其他�作。为解决这一问题,必须将�索与特定字段�系起�。通过利用代字� (?)
以�对特定字段的说明,�以达到这一目的,如下例所示:

$ awk ‘$5 ? /AR/’ emp_names

46019 BOGUE ROBERT PHOENIX AZ

46021 JUNE MICAH PHOENIX AZ

46022 KANE SHERYL UNKNOWN AZ

$

代字�(表示匹�)的对应符�是一个��带有感��的代字� (!?) 。这些字符通知程�,如果�索�列没有出现在指定字段中,则找出与�索�列相匹�的所有行:

$ awk ‘$5 !? /AR/’ names

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

46017 FELDMAN EVAN MOBILE AL

46018 SWIM STEVE UNKNOWN AL

46024 WOOD WILLIAM MUNCIE IN

46026 FERGUS SARAH MUNCIE IN

46027 BUCK SARAH MUNCIE IN

46029 TUTTLE BOB MUNCIE IN

$

在这�情况下,将显示第五个字段中没有 AR 的所有行 — 包括两个 Sarah �目,这两个�目确实包� AR ,但�是在第三个字段而�是第五个字段中。

花括�和字段分隔符

括�字符在 AWK 命令中起�很��的作用。出现在括�之间的�作指出将��生什么以�何时�生。当�使用一对括�时:

{print $3,$2}

括�间的所有�作�时�生。当使用多于一对的括�时:

{print $3}{print $2}

执行第一组命令,在该命令完��执行第二组命令。注�以下两列清�的区别:

$ awk ‘{print $3,$2}’ names

EVAN DULANEY

JEFF DURHAM

BILL STEEN

EVAN FELDMAN

STEVE SWIM

ROBERT BOGUE

MICAH JUNE

SHERYL KANE

WILLIAM WOOD

SARAH FERGUS

SARAH BUCK

BOB TUTTLE

$

 

$ awk ‘{print $3}{print $2}’ names

EVAN

DULANEY

JEFF

DURHAM

BILL

STEEN

EVAN

FELDMAN

STEVE

SWIM

ROBERT

BOGUE

MICAH

JUNE

SHERYL

KANE

WILLIAM

WOOD

SARAH

FERGUS

SARAH

BUCK

BOB

TUTTLE

$

�利用多组括�进行��查找,执行第一组中的命令直到完�为止;然�处�第二组命令。如果有第三组命令,则在第二组命令
完��执行它,以此类推。在所生�的打�输出中,有两个分隔的打�命令,因此先执行第一个命令,��执行第二个命令,这样导致�个�目显示在两行而�是一
行中。

区分两个字段的字段分隔符�一定始终是空格;它�以是任何�识别的字符。为进行演示,�定 emp_names 文件利用冒�而�是制表符�分隔字段:

$ cat emp_names

46012:DULANEY:EVAN: MOBILE : AL

46013: DURHAM :JEFF: MOBILE : AL

46015:STEEN:BILL: MOBILE : AL

46017:FELDMAN:EVAN: MOBILE : AL

46018:SWIM:STEVE:UNKNOWN: AL

46019:BOGUE:ROBERT: PHOENIX :AZ

46021:JUNE:MICAH: PHOENIX :AZ

46022:KANE:SHERYL:UNKNOWN:AR

46024:WOOD:WILLIAM: MUNCIE :IN

46026:FERGUS:SARAH: MUNCIE :IN

46027:BUCK:SARAH: MUNCIE :IN

46029:TUTTLE:BOB: MUNCIE :IN

$

如果试图通过指定所需�的第二个字段�打�姓�

$ awk ‘{print $2}’ emp_names

您最å?Žä¼šå¾—到å??二个空行。因为文件中没有空格,除了第一个字段之外没有å?¯è®¤åˆ«çš„字段。为解决这一问题,必须通知
AWK 是空格之外的�一个字符作为分隔符,有两�方法�通知 AWK 使用新的字段分隔符:使用命令行�数 -F ,或在程�中指定�� FS
。两�方法的效果相�,�有一�例外情况,如下例所示:

$ awk ‘{FS=”:”}{print $2}’ emp_names

 

DURHAM

STEEN

FELDMAN

SWIM

BOGUE

JUNE

KANE

WOOD

FERGUS

BUCK

TUTTLE

$

 

$ awk -F: ‘{print $2}’ emp_names

DULANEY

DURHAM

STEEN

FELDMAN

SWIM

BOGUE

JUNE

KANE

WOOD

FERGUS

BUCK

TUTTLE

$

在第一个命令中,头一�记录返回�正确的空行,而其他结果正确。直到读�第二�记录时,�识别字段分隔符并正确地执行。通过使用 BEGIN 语��以纠正这一缺点(在�文详述)。 -F 的功能�常类似于 BEGIN ,能够正确地读�第一�记录并按�求执行。

在本文开始处我曾æ??到,默认的显示 / 输出字段分隔符是空格。通过使用输出字段分隔符 ( OFS ) å?˜é‡?,å?¯ä»¥åœ¨ç¨‹åº?中更改此特性。例如,è¦?读å?–文件(由冒å?·åˆ†éš”)并以短划线显示,则命令是

$ awk -F”:” ‘{OFS=”-”}{print $1,$2,$3,$4,$5}’ emp_names

46012-DULANEY-EVAN-MOBILE-AL

46013-DURHAM-JEFF-MOBILE-AL

46015-STEEN-BILL-MOBILE-AL

46017-FELDMAN-EVAN-MOBILE-AL

46018-SWIM-STEVE-UNKNOWN-AL

46019-BOGUE-ROBERT-PHOENIX-AZ

46021-JUNE-MICAH-PHOENIX-AZ

46022-KANE-SHERYL-UNKNOWN-AR

46024-WOOD-WILLIAM-MUNCIE-IN

46026-FERGUS-SARAH-MUNCIE-IN

46027-BUCK-SARAH-MUNCIE-IN

46029-TUTTLE-BOB-MUNCIE-IN

$

FS 和 OFS 是(输入)字段分隔符和输出字段分隔符,它们�是一对�以在 AWK 实用工具中使用的��。例如,�在打�时为�行编�,�以采用以下方�使用 NR ��:

$ awk -F”:” ‘{print NR,$1,$2,$3}’ emp_names

1 46012 DULANEY EVAN

2 46013 DURHAM JEFF

3 46015 STEEN BILL

4 46017 FELDMAN EVAN

5 46018 SWIM STEVE

6 46019 BOGUE ROBERT

7 46021 JUNE MICAH

8 46022 KANE SHERYL

9 46024 WOOD WILLIAM

10 46026 FERGUS SARAH

11 46027 BUCK SARAH

12 46029 TUTTLE BOB

$

找出员工��处于 46012 和 46015 之间的所有行:

$ awk -F”:” ‘/4601[2-5]/’ emp_names

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

$

添加文本

�以按照添加控制�列或其他字符的相�方�将文本添加到显示中。例如,�将分隔符从空格改为冒�,则命令是

awk ‘{print $1″:”$2″:”$3″:”$4″:”$5}’ emp_names > new_emp_names

在这ç§?情况下,字符 ( : ) 包å?«åœ¨å¼•å?· ( “/” ) 中,它被添加到æ¯?个字段之间。在引å?·ä¹‹é—´çš„值å?¯ä»¥æ˜¯ä»»ä½•内容。例如,创建一个关于居ä½?在阿拉巴马州的员工的外观类似数æ?®åº“的显示:

$ awk ‘$5 ~ /AL/ {print “NAME: “$2″, “$3″\nCITY-STATE:

“$4″, “$5″\n”}’ emp_names

 

NAME: DULANEY, EVAN

CITY-STATE: MOBILE , AL

 

NAME: DURHAM , JEFF

CITY-STATE: MOBILE , AL

 

NAME: STEEN, BILL

CITY-STATE: MOBILE , AL

 

NAME: FELDMAN, EVAN

CITY-STATE: MOBILE , AL

 

NAME: SWIM, STEVE

CITY-STATE: UNKNOWN, AL

$

数学�作

AWK 除了æ??供文本功能,还æ??供全部范围的算术æ“?作符,包括以下符å?·ï¼š

+ 将数字相加
- �
* 乘
/ 除
^ 执行指数�算
% æ??供模
++ 将��值加一
+= 将其他�作的结果分�给��
— 将���一
-= 将�法�作的结果分�给��
*= 分�乘法�作的结果
/= 分�除法�作的结果
%= 分�求模�作的结果

例如,�定您的机器上存在以下的文件,详细地列出硬件商店中的物�:

$ cat inventory

hammers 5 7.99

drills 2 29.99

punches 7 3.59

drifts 2 4.09

bits 55 1.19

saws 123 14.99

nails 800 .19

screws 80 .29

brads 100 .24

$

第一项业务定�是通过将第二个字段(数�)的值乘以第三个字段(价格)的值,计算��物�的库存价值:

$ awk ‘{print $1,”QTY: “$2,”PRICE: “$3,”TOTAL: “$2*$3}’ inventory

hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95

drills QTY: 2 PRICE: 29.99 TOTAL: 59.98

punches QTY: 7 PRICE: 3.59 TOTAL: 25.13

drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18

bits QTY: 55 PRICE: 1.19 TOTAL: 65.45

saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77

nails QTY: 800 PRICE: .19 TOTAL: 152

screws QTY: 80 PRICE: .29 TOTAL: 23.2

brads QTY: 100 PRICE: .24 TOTAL: 24

$

如果这些行本身并���,您�是希望确定商店中有多少件物�,则�以分�一个普通��,按照��记录中的物�数�增加:

$ awk ‘{x=x+$2} {print x}’ inventory

5

7

14

16

71

194

994

1074

1174

$

根�这一数�,商店中有 1174 件物�。第一次执行时,�� x 没有值,因此它采用第一行第二个字段的值。第二次执行时,它�留了第一行的值并加上第二行的值,以此类推,直到达到累计的总�。

�以应用相�的过程�确定现有库存的总价值:

$ awk ‘{x=x+($2*$3)} {print x}’ inventory

39.95

99.93

125.06

133.24

198.69

2042.46

2194.46

2217.66

2241.66

$

因此, 1174 件物�的价值是 $2,241.66 。虽然这一过程�以获得总计值,但它的外观很差,需�加工�实际的报表。利用一些附加项,很容易使显示�得更整�:

$ awk ‘{x=x+($2*$3)}{print $1,”QTY: “$2,”PRICE: “$3,”TOTAL: “$2*$3,”BAL: “x}’ inventory

hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95 BAL: 39.95

drills QTY: 2 PRICE: 29.99 TOTAL: 59.98 BAL: 99.93

punches QTY: 7 PRICE: 3.59 TOTAL: 25.13 BAL: 125.06

drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18 BAL: 133.24

bits QTY: 55 PRICE: 1.19 TOTAL: 65.45 BAL: 198.69

saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77 BAL: 2042.46

nails QTY: 800 PRICE: .19 TOTAL: 152 BAL: 2194.46

screws QTY: 80 PRICE: .29 TOTAL: 23.2 BAL: 2217.66

brads QTY: 100 PRICE: .24 TOTAL: 24 BAL: 2241.66

$

该过程æ??供了æ¯?æ?¡è®°å½•的清å?•,å?Œæ—¶å°†æ€»ä»·å€¼åˆ†é…?给库存值,并ä¿?æŒ?商店资产的è¿?作平衡。

BEGIN 和 END

使用 BEGIN 和 END 语��以分别指定在处�实际开始之�或者完�之�进行�作。 BEGIN 语�最常用于建立��或显示标题。�一方�, END 语��用于在程�结��继续进行处�。

在��的示例中,利用以下例程生�了物�的总价值:

awk ‘{x=x+($2*$3)} {print x}’ inventory

该例程在�行总计累加时显示了文件中的�一行。没有其他方法�以指定它,而�让在�一行进行打�也导致它始终�打�出�。但是,利用 END 语��以��这一问题:

$ awk ‘{x=x+($2*$3)} END {print “Total Value of Inventory:”x}’ inventory

Total Value of Inventory: 2241.66

$

定义了�� x ,它对�一行进行处�;但是,在所有处�完�之��会生�显示。尽管�以作为独立例程使用,它也�以置入到先�的代�列表,添加更多信�并生�更完整的报表:

$ awk ‘{x=x+($2*$3)} {print $1,”QTY: “$2,”PRICE:

“$3,”TOTAL: “$2*$3} END {print “Total Value of Inventory: ” x}’ inventory

 

hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95

drills QTY: 2 PRICE: 29.99 TOTAL: 59.98

punches QTY: 7 PRICE: 3.59 TOTAL: 25.13

drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18

bits QTY: 55 PRICE: 1.19 TOTAL: 65.45

saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77

nails QTY: 800 PRICE: .19 TOTAL: 152

screws QTY: 80 PRICE: .29 TOTAL: 23.2

brads QTY: 100 PRICE: .24 TOTAL: 24

Total Value of Inventory: 2241.66

$

BEGIN 命令与 END 的工作方�相�,但它建立了那些需�在完�其他工作之�所�的项目。该过程最常�的目的是创建报表的标题。此例程的语法类似于

$ awk ‘BEGIN {print “ITEM QUANTITY PRICE TOTAL”}’

输入�输出和�文件

AWK 工具�以从文件中读�其输入,正如在此之�所有示例所�的那样,它也�以从其他命令的输出中获�输入。例如:

$ sort emp_names | awk ‘{print $3,$2}’

awk 命令的输入是排��作的输出。除了 sort ,还�以使用任何其他的 Linux 命令 — 例如 grep 。该过程�许您在离开所选定字段�对文件执行其他�作。

类似于解释程�, AWK 使用输出改��作符 > 和 >>
将其输出放入文件中而�是标准输出设备。这些符�的作用类似于它们在解释程�中的对应符�,因此 > 在�存在文件时创建文件,而
/>> 追加到现有文件的尾部。请看以下的示例:

$ awk ‘{print NR, $1 ) > “/tmp/filez” }’ emp_names

$ cat /tmp/filez

1 46012

2 46013

3 46015

4 46017

5 46018

6 46019

7 46021

8 46022

9 46024

10 46026

11 46027

12 46029

$

检查该语å?¥çš„语法,您会看到输出改å?‘是在打å?°è¯­å?¥å®Œæˆ?å?Žè¿›è¡Œçš„。必须将文件å??包å?«åœ¨å¼•å?·ä¸­ï¼Œå?¦åˆ™å®ƒå?ªæ˜¯ä¸€ä¸ªæœªåˆ?始化的
AWK ��,而将指令�接起�会在 AWK 中产生错误。(如果�正确地使用改�符�,则 AWK 无法了解该符��味� “ 改� �
还是一个关系�作符。)

在 AWK 中输出到管é?“也类似于解释程åº?中所实现的相å?Œæ“?作。è¦?将打å?°å‘½ä»¤çš„输出å?‘é€?到管é?“中,å?¯ä»¥åœ¨æ‰“å?°å‘½ä»¤å?Žé™„加管é?“符å?·ä»¥å?Šå‘½ä»¤çš„å??称,如下所示:

$ awk ‘{ print $2 | “sort” }’ emp_names

BOGUE

BUCK

DULANEY

DURHAM

FELDMAN

FERGUS

JUNE

KANE

STEEN

SWIM

TUTTLE

WOOD

$

这是输出改å?‘的情况,必须将命令包å?«åœ¨å¼•å?·ä¸­ï¼Œè€Œç®¡é?“çš„å??称是被执行命令的å??称。

AWK 所使用的命令å?¯ä»¥æ?¥è‡ªä¸¤ä¸ªåœ°æ–¹ã€‚首先,å?¯ä»¥åœ¨å‘½ä»¤è¡Œä¸­æŒ‡å®šå®ƒä»¬ï¼Œå¦‚示例中所示。其次,它们å?¯ä»¥ç”±æº?文件æ??供。如果是这ç§?情况,通过 -f 选项将这ç§?情况å?‘ AWK å?‘出警告。演示如下:

$ cat awklist

{print $3,$2}

{print $4,$5,”\n”}

$

 

$ awk -f awklist emp_names

EVAN DULANEY

MOBILE AL

 

JEFF DURHAM

MOBILE AL

 

BILL STEEN

MOBILE AL

 

EVAN FELDMAN

MOBILE AL

 

STEVE SWIM

UNKNOWN AL

 

ROBERT BOGUE

PHOENIX AZ

 

MICAH JUNE

PHOENIX AZ

 

SHERYL KANE

UNKNOWN AR

 

WILLIAM WOOD

MUNCIE IN

 

SARAH FERGUS

MUNCIE IN

 

SARAH BUCK

MUNCIE IN

 

BOB TUTTLE

MUNCIE IN

 

$

注æ„?,在æº?文件中的任何地方或者在命令行中调用它时,ä¸?使用å?•引å?·ã€‚å?•引å?·å?ªç”¨äºŽåŒºåˆ«å‘½ä»¤è¡Œä¸­çš„命令与文件å??称。

如果简�的输出�能处�您的程�中所需�的��信�,则�以�试由 printf 命令获得的更加��的输出,其语法是

printf( format, value, value …)

该语法类似于 C 语言中的 printf 命令,而格�的规格是相�的。通过�入一项定义如何打�数值的规格,�以定义该格�。格�规格包�一个跟有字�的 % 。类似于打�命令, printf �必包�在圆括�中,但是�以认为使用圆括�是一�良好的习惯。

下表列出 printf 命令æ??供的å?„ç§?规格。

 

è§„æ ¼

说明

%c

打��个 ASCII 字符

%d

打å?°å??进制数

%e

打�数字的科学计数表示

%f

打�浮点表示

%g

打� %e 或 %f ;两�方�都更简短

%o

打�无符�的八进制数

s

打� ASCII 字符串

%x

打å?°æ— ç¬¦å?·çš„å??六进制数

%%

打�百分�;�执行转�

å?¯ä»¥åœ¨ % 与字符之间æ??ä¾›æŸ?些附加的格å¼?化å?‚数。这些å?‚数进一步改进数值的打å?°æ–¹å¼?:

 

å?‚æ•°

说明

-

将字段中的表达��左对�

,width

根�需�将字段补�到指定宽度(�导零使用零将字段补�)

.prec

�数点��数字的最大字符串宽度或最大数�

 

printf 命令能够控制并将数值从一ç§?æ ¼å¼?转æ?¢ä¸ºå?¦ä¸€ç§?æ ¼å¼?。当需è¦?打å?°å?˜é‡?的值时,å?ªéœ€æ??供一ç§?规格,指示
printf 如何打�信�(通常包�在�引�中)��。必须为�个传递到 printf 的��包�一个规格�数;如果包�过少的�数,则
printf �会打�所有的数值。

处�错误

AWK 工具报告所å?‘生错误的方å¼?很令人æ?¼ç?«ã€‚一个错误会阻ç¢?任何æ“?作的进行,所æ??供的错误信æ?¯é?žå¸¸å?«æ··ä¸?清:

awk: syntax error near line 2

awk: bailing out near line 2

您�能会花几�时的时间查看第 2 行,试图找出它为什么阻�程��行;这就是支�使用�文件的一个有力论�。

切记有两�规则�以帮助您��出现语法错误:

1. 确�命令�于括�中,而括��于�引�中。没有使用这些字符之一必然导致程�无法�行。

2. �索命令需��于斜线之间。�找出�在�第安那州的员工,您必须使用 “ /IN/ � 而�是 “ IN � 。

______________________________________________ä¿?ç•™___________________________________________________

Sort �常与 uniq 命令一起使用,从已排�的文件中删除完全相�的行。uniq 命令在管�中�常跟在 sort 命令的��,还�以使用 -c 选项�计算�一行所出现的次数,或者使用 -d 选项,�报告完全相�的行:

$ sort -m test.out test2_sort.out | uniq -c
1 Another test.
1 Testing testing
2 This is a test.

  在这里我们�并两个文件 test.out 和 test2_sort.out。然�我们使用 -c 选项,将输出传�到 uniq,这样最�的结果是按字�顺�排列的列表,完全相�的行被删除,并带有一个关于�行出现频率的报告。

awk ‘{print $1}’ bigbrother_access_log.20050713 |sort |uniq -c |sort -rn |more

列出bigbrother_access_log.20050713 这个文件中第一个字段�一行所出现的次数 或者使用 -d 选项,�报告完全相�的行:

Technorati Tags:

Technorati Tags:


Leave a Comment

(required)

(required)



Formatting your comment
Back to Top | Textarea: Larger | Smaller