偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

通過兩個(gè)簡(jiǎn)單的教程來提高你的 awk 技能

系統(tǒng) Linux
awk 是 Unix 和 Linux 用戶工具箱中最古老的工具之一。超越單行的 awk 腳本,學(xué)習(xí)如何做郵件合并和字?jǐn)?shù)統(tǒng)計(jì)。

[[344424]]

超越單行的 awk 腳本,學(xué)習(xí)如何做郵件合并和字?jǐn)?shù)統(tǒng)計(jì)。

awk 是 Unix 和 Linux 用戶工具箱中最古老的工具之一。awk 由 Alfred Aho、Peter Weinberger 和 Brian Kernighan(即工具名稱中的 A、W 和 K)在 20 世紀(jì) 70 年代創(chuàng)建,用于復(fù)雜的文本流處理。它是流編輯器 sed 的配套工具,后者是為逐行處理文本文件而設(shè)計(jì)的。awk 支持更復(fù)雜的結(jié)構(gòu)化程序,是一門完整的編程語言。

本文將介紹如何使用 awk 完成更多結(jié)構(gòu)化的復(fù)雜任務(wù),包括一個(gè)簡(jiǎn)單的郵件合并程序。

awk 的程序結(jié)構(gòu)

awk 腳本是由 {}(大括號(hào))包圍的功能塊組成,其中有兩個(gè)特殊的功能塊,BEGIN 和 END,它們?cè)谔幚淼谝恍休斎肓髦昂妥詈笠恍刑幚碇髨?zhí)行。在這兩者之間,塊的格式為:

  1. 模式 { 動(dòng)作語句 }

當(dāng)輸入緩沖區(qū)中的行與模式匹配時(shí),每個(gè)塊都會(huì)執(zhí)行。如果沒有包含模式,則函數(shù)塊在輸入流的每一行都會(huì)執(zhí)行。

另外,以下語法可以用于在 awk 中定義可以從任何塊中調(diào)用的函數(shù)。

  1. function 函數(shù)名(參數(shù)列表) { 語句 }

這種模式匹配塊和函數(shù)的組合允許開發(fā)者結(jié)構(gòu)化的 awk 程序,以便重用和提高可讀性。

awk 如何處理文本流

awk 每次從輸入文件或流中一行一行地讀取文本,并使用字段分隔符將其解析成若干字段。在 awk 的術(shù)語中,當(dāng)前的緩沖區(qū)是一個(gè)記錄。有一些特殊的變量會(huì)影響 awk 讀取和處理文件的方式:

  • FS字段分隔符field separator)。默認(rèn)情況下,這是任何空格字符(空格或制表符)。
  • RS記錄分隔符record separator)。默認(rèn)情況下是一個(gè)新行(n)。
  • NF字段數(shù)number of fields)。當(dāng) awk 解析一行時(shí),這個(gè)變量被設(shè)置為被解析出字段數(shù)。
  • $0: 當(dāng)前記錄。
  • $1、$2、$3 等:當(dāng)前記錄的第一、第二、第三等字段。
  • NR記錄數(shù)number of records)。迄今已被 awk 腳本解析的記錄數(shù)。

影響 awk 行為的變量還有很多,但知道這些已經(jīng)足夠開始了。

單行 awk 腳本

對(duì)于一個(gè)如此強(qiáng)大的工具來說,有趣的是,awk 的大部分用法都是基本的單行腳本。也許最常見的 awk 程序是打印 CSV 文件、日志文件等輸入行中的選定字段。例如,下面的單行腳本從 /etc/passwd 中打印出一個(gè)用戶名列表:

  1. awk -F":" '{print $1 }' /etc/passwd

如上所述,$1 是當(dāng)前記錄中的第一個(gè)字段。-F 選項(xiàng)將 FS 變量設(shè)置為字符 :。

字段分隔符也可以在 BEGIN 函數(shù)塊中設(shè)置:

  1. awk 'BEGIN { FS=":" } {print $1 }' /etc/passwd

在下面的例子中,每一個(gè) shell 不是 /sbin/nologin 的用戶都可以通過在該塊前面加上匹配模式來打印出來:

  1. awk 'BEGIN { FS=":" } ! /\/sbin\/nologin/ {print $1 }' /etc/passwd

awk 進(jìn)階:郵件合并

現(xiàn)在你已經(jīng)掌握了一些基礎(chǔ)知識(shí),嘗試用一個(gè)更具有結(jié)構(gòu)化的例子來深入了解 awk:創(chuàng)建郵件合并。

郵件合并使用兩個(gè)文件,其中一個(gè)文件(在本例中稱為 email_template.txt)包含了你要發(fā)送的電子郵件的模板:

  1. From: Program committee <pc@event.org>
  2. To: {firstname} {lastname} <{email}>
  3. Subject: Your presentation proposal
  4.  
  5. Dear {firstname},
  6.  
  7. Thank you for your presentation proposal:
  8. {title}
  9.  
  10. We are pleased to inform you that your proposal has been successful! We
  11. will contact you shortly with further information about the event
  12. schedule.
  13.  
  14. Thank you,
  15. The Program Committee

而另一個(gè)則是一個(gè) CSV 文件(名為 proposals.csv),里面有你要發(fā)送郵件的人:

  1. firstname,lastname,email,title
  2. Harry,Potter,hpotter@hogwarts.edu,"Defeating your nemesis in 3 easy steps"
  3. Jack,Reacher,reacher@covert.mil,"Hand-to-hand combat for beginners"
  4. Mickey,Mouse,mmouse@disney.com,"Surviving public speaking with a squeaky voice"
  5. Santa,Claus,sclaus@northpole.org,"Efficient list-making"

你要讀取 CSV 文件,替換第一個(gè)文件中的相關(guān)字段(跳過第一行),然后把結(jié)果寫到一個(gè)叫 acceptanceN.txt 的文件中,每解析一行就遞增文件名中的 N。

把 awk 程序?qū)懺谝粋€(gè)叫 mail_merge.awk 的文件中。在 awk 腳本中的語句用 ; 分隔。第一個(gè)任務(wù)是設(shè)置字段分隔符變量和其他幾個(gè)腳本需要的變量。你還需要讀取并丟棄 CSV 中的第一行,否則會(huì)創(chuàng)建一個(gè)以 Dear firstname 開頭的文件。要做到這一點(diǎn),請(qǐng)使用特殊函數(shù) getline,并在讀取后將記錄計(jì)數(shù)器重置為 0。

  1. BEGIN {
  2.   FS=",";
  3.   template="email_template.txt";
  4.   output="acceptance";
  5.   getline;
  6.   NR=0;
  7. }

主要功能非常簡(jiǎn)單:每處理一行,就為各種字段設(shè)置一個(gè)變量 —— firstnamelastname、email 和 title。模板文件被逐行讀取,并使用函數(shù) sub 將任何出現(xiàn)的特殊字符序列替換為相關(guān)變量的值。然后將該行以及所做的任何替換輸出到輸出文件中。

由于每行都要處理模板文件和不同的輸出文件,所以在處理下一條記錄之前,需要清理和關(guān)閉這些文件的文件句柄。

  1. {
  2.         # 從輸入文件中讀取關(guān)聯(lián)字段
  3.         firstname=$1;
  4.         lastname=$2;
  5.         email=$3;
  6.         title=$4;
  7.  
  8.         # 設(shè)置輸出文件名
  9.         outfile=(output NR ".txt");
  10.  
  11.         # 從模板中讀取一行,替換特定字段,
  12.         # 并打印結(jié)果到輸出文件。
  13.         while ( (getline ln &lt; template) &gt; 0 )
  14.         {
  15.                 sub(/{firstname}/,firstname,ln);
  16.                 sub(/{lastname}/,lastname,ln);
  17.                 sub(/{email}/,email,ln);
  18.                 sub(/{title}/,title,ln);
  19.                 print(ln) &gt; outfile;
  20.         }
  21.  
  22.         # 關(guān)閉模板和輸出文件,繼續(xù)下一條記錄
  23.         close(outfile);
  24.         close(template);
  25. }

你已經(jīng)完成了! 在命令行上運(yùn)行該腳本:

  1. awk -f mail_merge.awk proposals.csv

  1. awk -f mail_merge.awk < proposals.csv

你會(huì)在當(dāng)前目錄下發(fā)現(xiàn)生成的文本文件。

awk 進(jìn)階:字頻計(jì)數(shù)

awk 中最強(qiáng)大的功能之一是關(guān)聯(lián)數(shù)組,在大多數(shù)編程語言中,數(shù)組條目通常由數(shù)字索引,但在 awk 中,數(shù)組由一個(gè)鍵字符串進(jìn)行引用。你可以從上一節(jié)的文件 proposals.txt 中存儲(chǔ)一個(gè)條目。例如,在一個(gè)單一的關(guān)聯(lián)數(shù)組中,像這樣:

  1.         proposer["firstname"]=$1;
  2.         proposer["lastname"]=$2;
  3.         proposer["email"]=$3;
  4.         proposer["title"]=$4;

這使得文本處理變得非常容易。一個(gè)使用了這個(gè)概念的簡(jiǎn)單的程序就是詞頻計(jì)數(shù)器。你可以解析一個(gè)文件,在每一行中分解出單詞(忽略標(biāo)點(diǎn)符號(hào)),對(duì)行中的每個(gè)單詞進(jìn)行遞增計(jì)數(shù)器,然后輸出文本中出現(xiàn)的前 20 個(gè)單詞。

首先,在一個(gè)名為 wordcount.awk 的文件中,將字段分隔符設(shè)置為包含空格和標(biāo)點(diǎn)符號(hào)的正則表達(dá)式:

  1. BEGIN {
  2. # ignore 1 or more consecutive occurrences of the characters
  3. # in the character group below
  4. FS="[ .,:;()<>{}@!\"'\t]+";
  5. }

接下來,主循環(huán)函數(shù)將遍歷每個(gè)字段,忽略任何空字段(如果行末有標(biāo)點(diǎn)符號(hào),則會(huì)出現(xiàn)這種情況),并遞增行中單詞數(shù):

  1. {
  2.         for (i = 1; i &lt;= NF; i++) {
  3.                 if ($i != "") {
  4.                         words[$i]++;
  5.                 }
  6.         }
  7. }

最后,處理完文本后,使用 END 函數(shù)打印數(shù)組的內(nèi)容,然后利用 awk 的能力,將輸出的內(nèi)容用管道輸入 shell 命令,進(jìn)行數(shù)字排序,并打印出 20 個(gè)最常出現(xiàn)的單詞。

  1. END {
  2.         sort_head = "sort -k2 -nr | head -n 20";
  3.         for (word in words) {
  4.                 printf "%s\t%d\n", word, words[word] | sort_head;
  5.         }
  6.         close (sort_head);
  7. }

在這篇文章的早期草稿上運(yùn)行這個(gè)腳本,會(huì)產(chǎn)生這樣的輸出:

  1. [dneary@dhcp-49-32.bos.redhat.com]$ awk -f wordcount.awk < awk_article.txt
  2. the 79
  3. awk 41
  4. a 39
  5. and 33
  6. of 32
  7. in 27
  8. to 26
  9. is 25
  10. line 23
  11. for 23
  12. will 22
  13. file 21
  14. we 16
  15. We 15
  16. with 12
  17. which 12
  18. by 12
  19. this 11
  20. output 11
  21. function 11

下一步是什么?

如果你想了解更多關(guān)于 awk 編程的知識(shí),我強(qiáng)烈推薦 Dale Dougherty 和 Arnold Robbins 所著的《Sed 和 awk》這本書。

awk 編程進(jìn)階的關(guān)鍵之一是掌握“擴(kuò)展正則表達(dá)式”。awk 為你可能已經(jīng)熟悉的 sed 正則表達(dá)式語法提供了幾個(gè)強(qiáng)大的補(bǔ)充。

另一個(gè)學(xué)習(xí) awk 的好資源是 GNU awk 用戶指南。它有一個(gè)完整的 awk 內(nèi)置函數(shù)庫的參考資料,以及很多簡(jiǎn)單和復(fù)雜的 awk 腳本的例子。 

責(zé)任編輯:龐桂玉 來源: Linux中國(guó)
相關(guān)推薦

2021-02-06 14:21:12

Linux 開發(fā)操作系統(tǒng)

2022-07-13 15:46:57

Python數(shù)據(jù)可視化代碼片段

2020-08-04 08:30:18

JS數(shù)組技巧

2011-03-01 13:07:36

MySQLOrder by查詢

2020-03-05 21:40:49

Javascript前端

2020-03-05 08:58:42

JavaScript語言開發(fā)

2022-07-08 14:50:12

時(shí)間管理技巧工作效率

2021-04-12 08:00:00

云存儲(chǔ)數(shù)據(jù)數(shù)據(jù)中心

2020-06-14 14:48:23

機(jī)器學(xué)習(xí)Python

2010-05-20 09:07:30

jQuery

2024-01-19 13:45:00

Pandas代碼深度學(xué)習(xí)

2022-08-20 19:12:22

編程竅門

2013-05-10 10:03:09

開源項(xiàng)目開源使用率集成商

2009-08-12 16:37:22

C#變量類型轉(zhuǎn)換

2010-05-28 09:57:50

TortoiseSVN

2020-04-06 12:20:51

Vim文本編輯器Linux

2019-10-08 15:27:18

掃雷BashLinux

2011-04-15 09:47:38

IntentActivityAndroid

2023-11-22 16:08:29

大數(shù)據(jù)提高數(shù)據(jù)質(zhì)量

2022-10-17 09:15:37

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)