龙空技术网

理解AWK,并用它挖掘亚马逊的好书排行榜

飞鱼在浪屿 56

前言:

此刻姐妹们对“python 求列表平均值”大概比较注重,你们都想要了解一些“python 求列表平均值”的相关知识。那么小编也在网摘上网罗了一些对于“python 求列表平均值””的相关文章,希望我们能喜欢,姐妹们一起来了解一下吧!

更多互联网精彩资讯、工作效率提升关注【飞鱼在浪屿】(日更新)

awk 非常简单。它只有几个约定和少量语法。因此,学习起来很简单,一旦你理解了它,它就会比你想象的更频繁地派上用场。

在这篇文章中,将教Awk 的基础知识。

计划

我将使用 Awk 查看书评并选择我的下一本书阅读。我将从简短的 Awk one-liners 开始,然后构建一个简单的 33 行程序,该程序根据 Amazon.com 上的 1900 万条评论对书籍进行排名。

什么是 awk

awk 是 Aho、Kernighan 和 Weinberger 于 1977 年编写的记录处理工具。它的名字是他们名字的首字母缩写。

他们在生产线处理工具sedgrep. awk 最初是作者的一个实验,目的是研究是否可以扩展文本处理工具来处理数字。grep搜索行,而 sed在行中进行替换,awk 旨在让您在行上进行计算。

如何安装gawk

学习 Awk 的最大原因是它几乎在每个 Linux 发行版上都有。您可能没有 perl 或 Python。只有最小的 linux 系统中的最小的才会没有它。甚至busybox 也包含awk。这就是它多么重要。

Awk 是便携式操作系统接口 (POSIX) 的一部分。这意味着它已经在MacBook 和Linux 服务器上。Awk 有多个版本,但对于基础知识,无论什么版本都可以。

$ awk --version
  GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)  Copyright (C) 1989, 1991-2020 Free Software Foundation.

安装 GNU Awk ( gawk)。Homebrew ( brew install gawk)。Windows 用户可以使用chocolatey ( choco install gawk)。如果使用 Linux,那么已经拥有了。

awk 打印

默认情况下,Awk 期望在标准输入上接收其输入并将其结果输出到标准输出。因此, awk 中做的最简单的事情就是打印一行输入。

$ echo "one two three" | awk '{ print }'one two three

您可以选择列(Awk 称之为字段):

$ echo "one two three" | awk '{ print $1 }'one$ echo "one two three" | awk '{ print $2 }'two$ echo "one two three" | awk '{ print $3 }'three

第一列是$1而不是$0,但$0是整行:

$ echo "one two three" | awk '{ print $0 }'
one two three

Awk 将每一行称为一条记录,将每一列称为一个字段。

可以跨多行执行此操作:

$ echo " one two three four five six" \ | awk '{ print $1 }'
onefour

可以打印不止一列:

$ echo " one two three four five six" \| awk '{ print $1, $2 }'
one twofour five

awk 还使用$NF用于访问最后一列:

$ echo " one two three four five six" \| awk '{ print $NF }'
threesix

学到了什么:Awk 字段变量

awk 为记录(行)($1, $2... $NF)中的每个字段(列)创建一个变量。$0指整个记录。

awk 样本数据

在本教程的其余部分,将使用亚马逊产品评论数据集的书籍。

该数据集包含来自亚马逊的产品评论和元数据,包括 1996 年 5 月至 2014 年 7 月的 1.428 亿条评论。

你可以像这样抓住它的书数据:

$ curl  | /  gunzip -c >> /   bookreviews.tsv

如果您想跟踪整个数据集,请对三个书籍文件 ( v1_00v1_01v1_02) 中的每一个重复此操作。

❗ 磁盘空间警告

如果你没有太多空间,你可以通过抓取第一个文件的前一万行来玩:

$ curl  \  | gunzip -c \  | head -n 10000 \  > bookreviews.tsv
图书资料

获取该数据后,您应该拥有如下所示的亚马逊书评数据:

marketplace customer_id review_id product_id product_parent product_title product_category star_rating helpful_votes total_votes vine verified_purchase review_headline review_body review_dateUS 22480053 R28HBXXO1UEVJT 0843952016 34858117 The Rising Books 5 0 0 N N Great Twist on Zombie Mythos I've known about this one for a long time, but just finally got around to reading it for the first time. I enjoyed it a lot!  What I liked the most was how it took a tired premise and breathed new life into it by creating an entirely new twist on the zombie mythos. A definite must read! 2012-05-03

该文件中的每一行代表一个书评记录。亚马逊对字段的布局如下:

DATA COLUMNS:01  marketplace       - 2 letter country code of the marketplace where the review was written.02  customer_id       - Random identifier that can be used to aggregate reviews written by a single author.03  review_id         - The unique ID of the review.04  product_id        - The unique Product ID the review pertains to. 05  product_parent    - Random identifier that can be used to aggregate reviews for the same product.06  product_title     - Title of the product.07  product_category  - Broad product category that can be used to group reviews 08  star_rating       - The 1-5 star rating of the review.09  helpful_votes     - Number of helpful votes.10  total_votes       - Number of total votes the review received.11  vine              - Review was written as part of the Vine program.12  verified_purchase - The review is on a verified purchase.13  review_headline   - The title of the review.14  review_body       - The review text.15  review_date       - The date the review was written.
打印书籍数据

我现在可以在更大的文件上测试,从打印关心的领域开始,比如市场:

$ awk '{ print $1 }' bookreviews.tsv | head 
marketplaceUSUSUSUSUSUSUSUSUS

或 customer_id:

$ awk '{ print $2 }' bookreviews.tsv | head 
customer_id224800534424445120357422132352082630178627780192130415465169233123108524

但是,当我尝试打印标题时,事情并不顺利:

$ awk '{ print $6 }' bookreviews.tsv | head 
product_titleTheStickyBlackDirectionUntilUnfinishedTheGoodPatterns

为了解决这个问题,需要配置字段分隔符。

字段分隔符

默认情况下,Awk 假定记录中的字段是用空格分隔。可以使用awk -F选项更改字段分隔符为制表符:

$ awk -F '\t' '{ print $6 }' bookreviews.tsv | head 
product_titleThe RisingSticky Faith Teen Curriculum with DVD: 10 Lessons to Nurture Faith Beyond High Black Passenger Yellow Cabs: Of Exile And Excess In JapanDirection and Destiny in the Birth ChartUntil the Next TimeUnfinished BusinessThe Republican Brain: The Science of Why They Deny Science- and RealityGood Food: 101 Cakes & BakesPatterns and Quilts (Mathzones)

学到了什么:Awk 字段分隔符

awk 假设记录中的字段是用空格分隔的。

可以使用这样的-F选项更改此设置

$ awk -F '\t' '{ print $6 }'

也可以使用NF.

$ awk -F '\t' '{ print $NF "\t" $(NF-2)}' bookreviews.tsv | head 
review_date     review_headline2012-05-03      Great Twist on Zombie Mythos2012-05-03      Helpful and Practical2012-05-03      Paul2012-05-03      Direction and Destiny in the Birth Chart2012-05-03      This was Okay2012-05-03      Excellent read!!!2012-05-03      A must read for science thinkers2012-05-03      Chocoholic heaven2012-05-03      Quilt Art Projects for Children

旁注:NF 和 NR

NF是一个保存记录中字段数的变量。所以我只是使用它的值作为索引来引用最后一个字段。

我可以像这样打印实际值:

$ awk -F '\t' '{ print NF }' bookreviews.tsv | head  
15151515151515151515

Awk 提供的另一个变量是NR,到目前为止的记录数。NR当我需要打印行号时很方便:

$ awk -F '\t' '{ print NR " " $(NF-2) }' bookreviews.tsv | head  
1 review_headline2 Great Twist on Zombie Mythos3 Helpful and Practical4 Paul5 Direction and Destiny in the Birth Chart6 This was Okay7 Excellent read!!!8 A must read for science thinkers9 Chocoholic heaven10 Quilt Art Projects for Children
正则表达式的 awk 模式匹配

Awk 的真正威力来自于模式匹配。你可以给 Awk 一个模式来匹配每一行,如下所示:

$ echo "aa        bb        cc" | awk '/bb/'bb

你可以这样换grep。:

$ echo "aa 10        bb 20        cc 30" | awk '/bb/{ print $2 }'20

使用这些知识,我可以轻松地按书名抓取评论并打印书名($6)和评论分数($8)。

我今天要关注的评论是针对《饥饿游戏》这本书的。我选择它是因为它是一个有很多评论的系列的一部分,我喜欢这部电影。所以我想知道我是否应该阅读它。

$ awk -F '\t' '/Hunger Games/{ print $6, $8  }' bookreviews.tsv | head
The Hunger Games (Book 1) 5The Hunger Games Trilogy Boxed Set 5The Hunger Games Trilogy: The Hunger Games / Catching Fire / Mockingjay 5Catching Fire |Hunger Games|2 4The Hunger Games (Book 1) 5Catching Fire |Hunger Games|2 5The Hunger Games Trilogy: The Hunger Games / Catching Fire / Mockingjay 5Blackout 3The Hunger Games Trilogy: The Hunger Games / Catching Fire / Mockingjay 4Tabula Rasa 3

我应该能够从这些评论中提取有价值的数据,但首先存在一个问题。我在这里收到不止一本书的评论。/Hunger Games/匹配行中的任何地方,我得到了各种“饥饿游戏”书籍。甚至在评论文本中看到提到“饥饿游戏”的书:

$ awk -F '\t' '/Hunger Games/{ print $6 }' bookreviews.tsv | sort | uniq    
BirthmarkedBlood Red RoadCatching Fire (The Hunger Games)DivergentEnclaveFire (Graceling Realm Books)Futuretrack 5Girl in the Arena...

我可以通过使用product_id字段模式匹配来解决这个问题:

$ awk -F '\t' '$4 == "0439023483"{ print $6 }' bookreviews.tsv | sort |  uniq The Hunger Games (The Hunger Games, Book 1)

我想计算“饥饿游戏”的平均评论分数,但首先,让我们看一下我们饥饿游戏评论的 review_date ( $15)、review_headline ( $13) 和star_rating ( $8)以感受一下数据:

$ awk -F '\t' '$4 == "0439023483"{ print $15 "\t" $13 "\t" $8}' bookreviews.tsv | head 
2015-08-19      Five Stars      52015-08-17      Five Stars      52015-07-23      Great read      52015-07-05      Awesome 52015-06-28      Epic start to an epic series    52015-06-21      Five Stars      52015-04-19      Five Stars      52015-04-12      i lile the book 32015-03-28      What a Great Read, i could not out it down   52015-03-28      Five Stars      5

看看那些星级评分。是的,这本书获得了许多 5 星评论,但更重要的是,我的文本表格的布局看起来很糟糕:评论标题的宽度打破了布局。

为了解决这个问题,我需要切换printprintf

学到了什么:Awk 模式匹配

了解到 awk 操作可以和模式一块使用,例如/regex/。如果没有模式,操作将在所有行上运行。

可以对模式使用简单的正则表达式。在这种情况下,它匹配行中的任何地方,例如grep:

$ awk '/hello/{ print "This line contains hello", $0}'

或者可以在特定字段内进行匹配:

$ awk '$4~/hello/{ print "This field contains hello", $4}'

或者可以精确匹配一个字段:

$ awk '$4 == "hello"{ print "This field is hello:", $4}'
awkprintf

printf像在 C 中一样工作,并使用格式字符串和值列表。您可以使用%s打印下一个字符串值。

所以我的print $15 "\t" $13 "\t" $8变成了printf "%s \t %s \t %s", $15, $13, $8.

可以添加右填充,并通过改变布局%s%-NsN是我想要的列宽:

$ awk -F '\t' '$4 == "0439023483"{ printf "%s \t %-20s \t %s \n", $15, $13, $8}' bookreviews.tsv | head 
2015-08-19       Five Stars              5 2015-08-17       Five Stars              5 2015-07-23       Great read              5 2015-07-05       Awesome                 5 2015-06-28       Epic start to an epic series    5 2015-06-21       Five Stars              5 2015-04-19       Five Stars              5 2015-04-12       i lile the book         3 2015-03-28       What a Great Read, i could not out it down   5 2015-03-28       Five Stars              5 

这张桌子非常接近我想要的。但是,有些标题太长了。我可以将它们缩短为 20 个字符substr($13,1,20)

把它们放在一起:

$ awk -F '\t' '$4 == "0439023483"{ printf "%s \t %-20s \t %s \n", $15, substr($13,1,20), $8}' bookreviews.tsv | head
2015-08-19       Five Stars              5 2015-08-17       Five Stars              5 2015-07-23       Great read              5 2015-07-05       Awesome                 5 2015-06-28       Epic start to an epi    5 2015-06-21       Five Stars              5 2015-04-19       Five Stars              5 2015-04-12       i lile the book         3 2015-03-28       What a Great Read, i    5 2015-03-28       Five Stars              5 

我学到了什么:printf和内置插件

如果需要打印表格,Awk 可以使用printf内置函数substr来格式化输出。

它最终看起来像这样:

$ awk '{ printf "%s \t %-5s", $1, substr($2,1,5)}'

printf很像 C 的工作方式printf。您可以使用%s将字符串插入到格式字符串中,其他标志让您设置宽度或精度。有关printf或其他内置函数的更多信息,您可以查阅 awk 参考文档。

awkBEGIN和END动作

我想计算这个数据集中书评的平均评分。为此,我需要使用一个变量。但是,我不需要声明变量或其类型。我可以使用它:

我可以$8像这样累加并打印出 review_stars ( )的运行总数:

$ awk -F '\t' '{ total = total + $8; print total }' bookreviews.tsv | head 
0510...

并将其转化为平均值,我可以使用NR来获取记录总数并END在处理结束时运行一个操作。

$ awk -F '\t' '    { total = total + $8 }END { print "Average book review:", total/NR, "stars" }' bookreviews.tsv | head 
Average book review is 4.24361 stars

我还可以使用BEGIN在 awk 开始处理记录之前运行一个操作。

 $ awk -F '\t' 'BEGIN { print "Calculating Average ..." }       { total = total + $8 }END   { print "Average book review:", total/NR, "stars" }' bookreviews.tsv 
Calculating Average ...Average book review is 4.24361 stars

学到的东西:awk的BEGINEND和变量

awk 提供了两种特殊的模式,BEGINEND. 可以使用它们在处理记录之前和之后运行操作。例如,这就是您在 Awk 中初始化数据、或执行任何启动或拆卸操作的方式。

最终看起来像这样:

$ awk 'BEGIN { print "start up" }      { print "line match" }END   { print "tear down" }'

还可以轻松地在 awk 中使用变量。不需要声明。

$ awk -F '{ total = total + $8 }'
有趣的 Awk One-Liners

看些真实示例,每天何时使用 Awk。以下是例子。

打印具有人类可读大小的文件:

$ ls -lh | awk '{ print $5,"\t", $9 }'  
7.8M     The_AWK_Programming_Language.pdf6.2G     bookreviews.tsv

获取正在运行的 docker 容器的 containerID:

$ docker ps -a |  awk '{ print $1 }'
CONTAINER08488f220f763b7fc673649f

您可以将最后一个与正则表达式结合起来,专注于您关心的一行。在这里我停止postgres,不管它的标签名称是什么:

$ docker stop "$(docker ps -a |  awk '/postgres/{ print $1 }')"

如果您有一个由某些工具返回的以空格分隔的文本表,那么 Awk 可以轻松地将其切片和切块。

旁注:为什么使用 awk 脚本

一个自然的问题是“为什么不使用 Python?它不擅长这种事情吗?

有几个答案。

首先,Awk 非常适合编写程序,这些程序的核心是对某些输入进行美化的 for 循环。如果这就是你正在做的,并且控制流有限,那么使用 awk 会比 Python 更简洁。

其次,如果你需要在某个时候将你的 Awk 程序改写成 Python。它不会超过 100 行代码,而且翻译过程会很简单。

第三,为什么不呢?学习新工具会很有趣。

我们现在已经从单行代码过渡到了 awk 脚本。使用 Awk,过渡是平滑的。我现在可以将 awk 嵌入到 bash 脚本中:

$ cat average
exec awk -F '\t' '{ total = total + $8 }END { print "Average book review is", total/NR, "stars" } ' $1
$ average bookreviews.tsv
Average book review is 4.2862 stars

或者我可以使用shebang ( #!):

$ cat average.awk
#!/usr/bin/env -S gawk -fBEGIN { FS = "\t" }{ total = total + $8 }END { print "Average book $6 review is", total/NR, "stars" } 

并像这样运行它

$ ./average.awk bookreviews.tsv

或者也可以使用-f以下命令直接将其传递给 awk :

$ awk -f average.awk bookreviews.tsv

旁注:BEGIN FS

如果使用 shebang 或直接传递给 Awk,在BEGIN操作中设置FS = "\t",使用文件分隔符。

BEGIN { FS = "\t" }
awk 平均示例

此时,可以开始计算饥饿游戏的评论分数了:

exec awk -F '\t' '$4 == "0439023483"{ title=$6; count = count + 1; total = total + $8 }END { print "The Average book review for", title, "is", total/count, "stars" }  ' $1

现在我在一个文件中,我可以更好地格式化它,以便更容易阅读:

$4 == "0439023483" {   title=$6  count = count + 1;   total = total + $8 }END {   printf "Book: %-5s\n", title  printf "Average Rating: %.2f\n", total/count }  

无论哪种方式,我都会得到以下输出:

Book: The Hunger Games (The Hunger Games, Book 1)Average Rating: 4.67%       

学到了什么:从文件中调用 Awk

一旦超出一行,就可以将 awk 脚本放入文件中。

然后可以使用该-f选项调用您的程序

$ awk -f file.awk input

使用shebang:

#!/usr/bin/env -S gawk -f

或使用 bashexec命令:

exec awk -F '\t' 'print $0' $1
awk 数组

我想知道该系列是否保持强大,或者它是否是三部曲的一本好书。如果评论迅速下降,那么这不是一个好兆头。我应该能够看到哪本书被评为最好,哪本书最差。让我们来了解一下。

如果我要在 Python 中计算平均值,我会遍历评论列表并使用字典来跟踪每个评论的总星级和总评论。

在 awk 中,我也可以这样做:

BEGIN { FS = "\t" }$6~/\(The Hunger Games(, Book 1)?\)$/ {   title[$6]=$6  count[$6]= count[$6] + 1  total[$6]= total[$6] + $8}END {     for (i in count) {        printf "---------------------------------------\n"        printf "%s\n", title[i]        printf "---------------------------------------\n"        printf "Ave: %.2f\t Count: %s \n\n", total[i]/count[i], count[i]      }}
$ awk -f hungergames.awk bookreviews.tsv
---------------------------------------The Hunger Games (The Hunger Games, Book 1)---------------------------------------Ave: 4.55        Count: 1497 ---------------------------------------Mockingjay (The Hunger Games)---------------------------------------Ave: 3.77        Count: 3801 ---------------------------------------Catching Fire (The Hunger Games)---------------------------------------Ave: 4.52        Count: 2205 ---------------------------------------

该系列的第一本书是最受欢迎的。最后一本书,Mockingjay 不那么受欢迎。所以这不是一个好兆头。

让我看看另一个三部曲,看看排名的逐渐下降是常见的还是饥饿游戏特有的:

BEGIN { FS = "\t" }$6~/\(The Lord of the Rings, Book .\)$/ {  # <-- changed this line  title[$6]=$6  count[$6]= count[$6] + 1  total[$6]= total[$6] + $8}END {     for (i in title) {        printf "---------------------------------------\n"        printf "%s\n", title[i]        printf "---------------------------------------\n"        printf "Ave: %.2f\t Count: %s \n\n", total[i]/count[i], count[i]      }}
---------------------------------------The Return of the King (The Lord of the Rings, Book 3)---------------------------------------Ave: 4.79        Count: 38 ---------------------------------------The Two Towers (The Lord of the Rings, Book 2)---------------------------------------Ave: 4.64        Count: 56 ---------------------------------------The Fellowship of the Ring (The Lord of the Rings, Book 1)---------------------------------------Ave: 4.60        Count: 93  

指环王有不同的模式。这些书都在一个非常狭窄的范围内。评论数量也少得多,所以很难肯定《王者归来》是最好的书,但它看起来确实如此。

学到了什么:Awk 关联数组

Awk 构建了关联数组,您可以像使用 Python 字典一样使用它们。

arr["key1"] = "one"arr["key2"] = "two"arr["key3"] = "three"

然后,可以使用 for 循环来迭代它们:

for (i in arr){    print $i, arr[i]}
key1 onekey2 twokey3 three

对于 1977 年编写的语言来说还不错!

awkIfElse

我讨厌亚马逊上的每本书的星级都在 3.0 到 4.5 星之间。仅仅根据数字很难判断。所以让我们根据平均值重新调整。也许如果我将评论标准化,就更容易确定 Mockingjay 的 3.77 平均分的好坏。

首先,我需要计算全局平均值,但将每一行的总数和平均值相加:

{    # Global Average    g_count = g_count + 1    g_total = g_total + $8 }

然后我计算全球平均值:

END {     g_score = g_total/g_count     ...}    

一旦我有了这个,我就可以根据书籍比平均水平高或低的程度来评分。我需要做的就是在我的END模式中添加一些 if 语句来完成这个:

END {     g_score = g_total/g_count     for (i in count) {        score = total[i]/count[i]        printf "%-30s\t", substr(title[i],1,30)        if (score - g_score > .5)            printf ""         else if (score - g_score > .25)            printf ""         else if (score - g_score > 0)            printf ""         else if (g_score - score  > 1)            printf ""         else if (g_score - score  > .5)            printf ""         else if (g_score - score  > 0)            printf ""        printf "\n"    }}

分区的值只是一个猜测,但它使我更容易理解排名:

The Hunger Games (The Hunger G  Catching Fire: The Official Il  Mockingjay (The Hunger Games)   The Two Towers (The Lord of th  The Fellowship of the Ring (Th  The Return of the King (The Lo  

看起来 Mockingjay,至少在亚马逊和这个数据集中,并没有受到好评。

可以轻松修改此脚本以查询特别的书籍:

exec gawk -F '\t' '{    # Global Average    g_count = g_count + 1    g_total = g_total + $8     PROCINFO["sorted_in"] = "@val_num_asc"}$6~/^.*'+"$1"+'.*$/ { # <-- Take match as input  title[$6]=$6  count[$6]= count[$6] + 1  total[$6]= total[$6] + $8}END {     PROCINFO["sorted_in"] = "@val_num_desc"    g_score = g_total/g_count     for (i in count) {        score = total[i]/count[i]        printf "%-50s\t", substr(title[i],1,50)        if (score - g_score > .4)            printf ""         else if (score - g_score > .25)            printf ""         else if (score - g_score > 0)            printf ""         else if (g_score - score  > 1)            printf ""         else if (g_score - score  > .5)            printf ""         else if (g_score - score  > 0)            printf ""        printf "\n"    }}' bookreviews.tsv | head -n 1

然后像这样运行它:

$ ./average "Left Hand of Darkness"The Left Hand of Darkness (Ace Science Fiction)         $ ./average "Neuromancer"          Neuromancer                                             $ ./average "The Lifecycle of Software Objects"The Lifecycle of Software Objects                       

这些都是好书,所以我开始质疑亚马逊评论家的品味。

不过,我想再测试一件事:最受欢迎的书籍排名如何?也许流行书籍获得了很多评论,这使它们低于整体平均水平?

学到了什么:Awk If Else

Awk 有分支 usingifelse语句。它的工作方式与您可能期望的完全一样:

$ echo "1\n 2\n 3\n 4\n 5\n 6" | awk '{        if (NR % 2)             print "odd"        else            print $0        }'
odd2odd4odd6
Awk 按值排序

Awk(特别是 gawk)允许使用PROCINFO["sorted_in"]. 这意味着,如果将程序更改为按值排序并取消过滤,那么我将能够看到评论最多的书籍:

exec gawk -F '\t' '{    # Global Average    g_count = g_count + 1    g_total = g_total + $8     title[$6]=$6    count[$6]= count[$6] + 1    total[$6]= total[$6] + $8}END {     PROCINFO["sorted_in"] = "@val_num_desc" # <-- Print in value order    g_score = g_total/g_count     for (i in count) {        score = total[i]/count[i]        printf "%-50s\t", substr(title[i],1,50)        if (score - g_score > .4)            printf ""         else if (score - g_score > .25)            printf ""         else if (score - g_score > 0)            printf ""         else if (g_score - score  > 1)            printf ""         else if (g_score - score  > .5)            printf ""         else if (g_score - score  > 0)            printf ""        printf "\n"    }}' bookreviews.tsv 

运行它:

$ ./top_books | head
Harry Potter And The Sorcerer's Stone                 Fifty Shades of Grey                                  The Hunger Games (The Hunger Games, Book 1)           The Hobbit                                            Twilight                                              Jesus Calling: Enjoying Peace in His Presence         Unbroken: A World War II Story of Survival, Resili    The Shack: Where Tragedy Confronts Eternity           Divergent                                             Gone Girl                                             

看起来评论最多的书籍中约有一半 (6 /10) 比平均水平更受欢迎。所以我不能把 Mockingjay 的低分归咎于它的受欢迎程度。我想我必须通过这个系列或至少那本书。

结论

一个好的程序员使用最强大的工具来完成工作。一个伟大的程序员使用最不强大的工具来完成这项工作。

awk 的功能远不止这些。还有更多的内置变量和内置函数。它具有范围模式和替换规则,您可以轻松地使用它来修改内容,而不仅仅是添加内容。

如果您想了解更多关于 Awk 的信息,The Awk Programming Language是一本权威书籍。它深入地涵盖了语言。它还涵盖了如何用 awk 构建小型编程语言,如何用 awk 构建数据库,以及其他一些有趣的项目。

甚至亚马逊也认为它很棒:

$ ./average "The AWK "          The AWK Programming Language                            

标签: #python 求列表平均值 #awkpython