awk 脚本_AWK单行代码和脚本可帮助您对文本文件进行排序

 2023-09-18 阅读 25 评论 0

摘要:awk 脚本 Awk是普遍存在的Unix命令,用于扫描和处理包含可预测模式的文本。 但是,由于它具有功能,因此也有理由将其称为编程语言。 令人困惑的是,awk有多个。 (或者,如果您认为只有一个,那么就会有几个克隆。)有awk

awk 脚本

Awk是普遍存在的Unix命令,用于扫描和处理包含可预测模式的文本。 但是,由于它具有功能,因此也有理由将其称为编程语言。

令人困惑的是,awk有多个。 (或者,如果您认为只有一个,那么就会有几个克隆。)有awk ,它是Aho,Weinberger和Kernighan编写的原始程序,然后是nawkmawk和GNU版本gawk 。 GNU版本的awk是该实用程序的高度可移植的免费软件版本,具有几个独特的功能,因此本文是关于GNU awk的。

虽然它的正式名称是gawk,但在GNU + Linux系统上,它的别名是awk,并用作该命令的默认版本。 在其他不随GNU awk一起提供的系统上,您必须安装它并将其称为gawk,而不是awk。 本文互换使用术语awk和gawk。

作为命令和编程语言,awk成为了强大的工具,可用于执行可能会被排序剪切uniq和其他常见实用程序使用的任务。 幸运的是,开放源代码中有很多冗余空间,因此,如果您面临是否使用awk的问题,答案可能是肯定的“也许”。

awk命令详解。 awk的灵活性之美在于,如果您已经致力于使用awk来完成一项任务,那么不管接下来发生什么,您都可以继续使用awk。 这包括对数据排序的永恒需求,而不是将数据交付给您的顺序。

样品套装

在探索awk的排序方法之前,请生成要使用的样本数据集。 保持简单,这样您就不会为极端情况和意想不到的复杂性所困扰。 这是本文使用的样本集:

Aptenodytes;forsteri;Miller,JF;1778;Emperor
Pygoscelis;papua;Wagler;1832;Gentoo
Eudyptula;minor;Bonaparte;1867;Little Blue
Spheniscus;demersus;Brisson;1760;African
Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
Torvaldis;linux;Ewing,L;1996;Tux

这是一个很小的数据集,但是它提供了多种数据类型:

  • 属名和种名,彼此相关但被认为是分开的
  • 姓,有时以逗号开头
  • 代表日期的整数
  • 任意术语
  • 所有字段均以分号分隔

根据您的教育背景,您可能会认为这是2D数组或表格,或者只是行分隔的数据集合。 您如何看待它取决于您,因为awk除了文本外没有其他期望。 由您决定告诉awk您想如何解析它。

排序作弊

如果您只想按特定的,可定义的字段(例如电子表格中的“单元格”)对文本数据集进行排序,则可以使用sort命令 。

字段和记录

无论输入的格式如何,都必须在其中找到模式,以便您可以专注于对您重要的数据部分。 在此示例中,数据由两个因素定界:线条和字段。 每行都代表一个新记录 ,就像您可能在电子表格或数据库转储中看到的那样。 在每一行中,存在用分号(;)分隔的不同字段 (将其视为电子表格中的单元格)。

代码、 Awk一次只处理一条记录,因此,当您在结构化对awk的说明时,您可以只关注一行。 建立您想要用一行编写的内容,然后在下一行中进行(无论是心理上还是用awk进行测试)等等。 最后,您将对awk脚本为提供所需数据结构而必须执行的操作做出很好的假设。

在这种情况下,很容易看到每个字段都用分号分隔。 为简单起见,假设您要按每行的第一字段对列表进行排序。

在进行排序之前,您必须能够仅将awk集中在每行的第一个字段上,因此这是第一步。 终端中awk命令的语法为awk ,后跟相关选项,然后是awk命令,最后是要处理的数据文件。

$ awk --field-separator = ";" '{print $1;}' penguins.list
Aptenodytes
Pygoscelis
Eudyptula
Spheniscus
Megadyptes
Eudyptes
Torvaldis

因为字段分隔符是对Bash shell具有特殊含义的字符,所以必须将分号括在引号中或在其前面加上反斜杠。 此命令仅用于证明您可以专注于特定领域。 您可以使用另一个字段的编号尝试相同的命令,以查看数据的另一个“列”的内容:

$ awk --field-separator = ";" '{print $3;}' penguins.list
Miller,JF
Wagler
Bonaparte
Brisson
Milne-Edwards
Viellot
Ewing,L

尚未进行任何排序,但这是良好的基础。

脚本编写

Awk不仅仅是命令。 它是一种具有索引,数组和函数的编程语言。 这很重要,因为这意味着您可以获取要排序的字段列表,将列表存储在内存中,进行处理,然后打印结果数据。 对于诸如此类的一系列复杂操作,在文本文件中进行操作会更容易,因此请创建一个名为sorter.awk的新文件并输入以下文本:

#!/usr/bin/awk -f

BEGIN {
FS = ";" ;
}

awk 排序按指定列排序、 这会将文件建立为awk脚本,该脚本执行文件中包含的行。

BEGIN语句是awk提供的特殊设置功能,用于只需要执行一次的任务。 定义内置变量FS ,它代表字段分隔符,并且与在--field-separator中的awk命令中设置的值相同,只需执行一次,因此它包含在BEGIN语句中。

AWK中的数组

您已经知道如何使用$表示法和字段号来收集特定字段的值,但是在这种情况下,您需要将其存储在数组中,而不是将其打印到终端。 这是通过awk数组完成的。 awk数组的重要之处在于它包含键和值。 想象一下有关本文的内容; 它看起来像这样: author:“ seth”,title:“如何用awk排序”,长度:1200 。 诸如作者标题长度之类的元素是键,以下内容为值。

在排序的上下文中,这样做的好处是可以将任何字段分配为键,将任何记录分配为值,然后使用内置的awk函数asorti() (按索引排序)按键进行排序。 现在,假定任意你需要通过第二个字段进行排序。

没有特殊关键字BEGINEND开头的Awk语句是在每个记录处发生的循环。 这是脚本的一部分,该脚本扫描数据中的模式并进行相应的处理。 每当awk将注意力转移到一条记录时,都会执行{}中的语句(除非后面带有BEGINEND )。

要将键和值添加到数组,请创建一个包含数组的变量(在本示例脚本中,我将其称为ARRAY ,它并不是很原始,但非常清晰),然后在方括号中将键和值赋给它等号( = )。

{   # dump each field into an array
ARRAY [ $2 ] = $R ;
}

awk命令。 在此语句中,第二个字段( $ 2 )的内容用作关键字,而当前记录( $ R )用作值。

asorti()函数

除了数组,awk还具有一些基本功能,您可以将它们用作常见任务的快速简便的解决方案。 GNU awk中引入的功能之一asorti()提供了按键(或index )或值对数组进行排序的功能。

您只能在对数组进行填充后对其进行排序,这意味着此操作不能对每个新记录都发生,而只能对脚本的最后阶段进行。 为此,awk提供了特殊的END关键字。 与BEGIN相反, END语句仅在扫描所有记录之后发生一次。

将此添加到您的脚本:

END {
asorti ( ARRAY,SARRAY ) ;
# get length
j = length ( SARRAY ) ;

for ( i = 1 ; i < = j; i++ ) {
printf ( "%s %s \n " , SARRAY [ i ] ,ARRAY [ SARRAY [ i ] ] )
}
}

asorti()函数获取ARRAY的内容,按索引对其进行排序,然后将结果放入一个名为SARRAY的新数组中(我在本文中发明的任意名称,即Sorted ARRAY )。

接下来,为变量j (另一个任意名称)分配给length()函数的结果,该函数计算SARRAY中的项

awk获取指定字符串? 最后,使用for循环使用printf()函数遍历SARRAY中的每个项以打印每个键,然后打印该键在ARRAY中的对应值。

运行脚本

要运行awk脚本,使其可执行:

 $  chmod +x sorter.awk 

然后针对penguin.list示例数据运行它:

$ . / sorter.awk penguins.list
antipodes Megadyptes;antipodes;Milne-Edwards; 1880 ;Yellow-eyed
chrysocome Eudyptes;chrysocome;Viellot; 1816 ;Sothern Rockhopper
demersus Spheniscus;demersus;Brisson; 1760 ;African
forsteri Aptenodytes;forsteri;Miller,JF; 1778 ;Emperor
linux Torvaldis;linux;Ewing,L; 1996 ;Tux
minor Eudyptula;minor;Bonaparte; 1867 ;Little Blue
papua Pygoscelis;papua;Wagler; 1832 ;Gentoo

如您所见,数据按第二个字段排序。

这有点限制性。 最好可以在运行时灵活选择要用作排序键的字段,以便可以在任何数据集上使用此脚本并获得有意义的结果。

添加命令选项

您可以通过在脚本中使用文字值var将命令变量添加到awk脚本中。 更改脚本,以使迭代子句在创建数组时使用var

{ # dump each field into an array
ARRAY [ $var ] = $R ;
}

awk脚本、 尝试运行脚本,以便在执行脚本时使用-v var选项将其按第三字段排序:

$ . / sorter.awk -v var = 3 penguins.list
Bonaparte Eudyptula;minor;Bonaparte; 1867 ;Little Blue
Brisson Spheniscus;demersus;Brisson; 1760 ;African
Ewing,L Torvaldis;linux;Ewing,L; 1996 ;Tux
Miller,JF Aptenodytes;forsteri;Miller,JF; 1778 ;Emperor
Milne-Edwards Megadyptes;antipodes;Milne-Edwards; 1880 ;Yellow-eyed
Viellot Eudyptes;chrysocome;Viellot; 1816 ;Sothern Rockhopper
Wagler Pygoscelis;papua;Wagler; 1832 ;Gentoo

修正

本文演示了如何在纯GNU awk中对数据进行排序。 该脚本可以进行改进,因此,如果对您有用,请花一些时间在gawk的手册页上研究awk函数 ,并自定义脚本以获得更好的输出。

这是到目前为止的完整脚本:

#!/usr/bin/awk -f
# GPLv3 appears here
# usage: ./sorter.awk -v var=NUM FILE

BEGIN { FS = ";" ; }

{ # dump each field into an array
ARRAY [ $var ] = $R ;
}

END {
asorti ( ARRAY,SARRAY ) ;
# get length
j = length ( SARRAY ) ;

for ( i = 1 ; i < = j; i++ ) {
printf ( "%s %s \n " , SARRAY [ i ] ,ARRAY [ SARRAY [ i ] ] )
}
}

翻译自: https://opensource.com/article/19/11/how-sort-awk

awk 脚本

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/72845.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息