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: AWKShellScripts
Technorati Tags: AWKShellScripts
Leave a Comment