命令中各短语没有固定顺序_linux中awk命令_命令中的竖杠怎么打

Awk是一个强悍的工具,可以执行个别可能由其它常见实用程序(包括sort)来完成的任务。--SethKenlon(作者)

Awk是个普遍存在的Unix命令,用于扫描和处理包含可预测模式的文本。并且,因为它具有函数功能,因而也可以合理地称之为编程语言。

令人疑惑的是,有不止一个awk。(或则,假如你觉得只有一个,这么其它几个就是克隆。)有awk(由Aho、Weinberger和Kernighan编撰的原始程序),之后有nawk、mawk和GNU版本的gawk。GNU版本的awk是该实用程序的一个高度可移植的自由软件版本,具有几个奇特的功能,因而本文是关于GNUawk的。

其实它的即将名称是gawk,但在GNU+Linux系统上,它的别称是awk,并用作该命令的默认版本。在其他没有带有GNUawk的系统上,你必须先安装它并将其称为gawk,而不是awk。本文互换使用术语awk和gawk。

awk既是命令语言又是编程语言,这使其成为一个强悍的工具,可以处理先前留给sort、cut、uniq和其他常见实用程序的任务。辛运的是,开源中有好多冗余空间,因而,假如你面临是否使用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

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

按照你的教育背景,你可能会觉得这是二维链表或表格,或则只是行分隔的数据集合。你怎么看待它只是你的问题,而awk只认识文本。由你决定告诉awk你想怎么解析它。

只想排序

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

数组和记录

命令中各短语没有固定顺序_命令中的竖杠怎么打_linux中awk命令

无论输入的格式怎样,都必须在其中找到模式才可以专注于对你重要的数据部份。在此示例中,数据由两个诱因定界:行和数组。每行都代表一个新的记录,就如你在电子表格或数据库轮询中见到的一样。在每一行中,都有用分号(;)分隔的不同的数组(将其视为电子表格中的单元格)。

awk一次只处理一条记录,因而,当你在构造发给awk的这指令时,你可以只关注一行记录。写下你想对一行数据执行的操作,之后在下一行进行测试(无论是心理上还是用awk进行测试),之后再进行其它的一些测试。最后,你要对你的awk脚本要处理的数据做好假定,便于可以按你要的数据结构提供给你数据。

在这个事例中,很容易看见每位数组都用分号隔开。为简单起见,假定你要按每行的第一数组对列表进行排序。

在进行排序之前,你必须才能让awk只关注在每行的第一个数组上,因而这是第一步。终端中awk命令的句型为awk,后跟相关选项,最后是要处理的数据文件。

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

由于数组分隔符是对Bashshell具有特殊涵义的字符,所以必须将分号括在冒号中或在其后面加上反斜杠。此命令仅用于证明你可以专注于特定数组。你可以使用另一个数组的编号尝试相同的命令linux中awk命令,以查看数据的另一个“列”的内容:

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

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

脚本编程

命令中各短语没有固定顺序_命令中的竖杠怎么打_linux中awk命令

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

#!/bin/gawk -f
BEGIN {
        FS=";";
}

这会将该文件构建为awk脚本,该脚本中包含执行的行。

BEGIN句子是awk提供的特殊设置功能,用于只须要执行一次的任务。定义外置变量FS,它代表数组分隔符(fieldseparator),而且与你在awk命令中使用--field-separator设置的值相同,它只需执行一次,因而它包含在BEGIN句子中。

awk中的字段

你已然晓得怎样通过使用$符号和数组编号来搜集特定数组的值,并且在这些情况下,你须要将其储存在链表中而不是将其复印到终端。这是通过awk链表完成的。awk链表的重要之处在于它包含键和值。想像一下有关本文的内容;它看上去像这样:author:”seth”,title:”Howtosortwithawk”,length:1200。例如作者、标题和宽度之类的元素是键,跟随的内容为值。

在排序的上下文中这样做的益处是,你可以将任何数组分配为键,将任何记录分配为值,之后使用外置的awk函数asorti()(按索引排序)键盘进行排序。如今,随意假定你只想按第二个数组排序。

没有被特殊关键字BEGIN或END造成来的awk句子是在每位记录都要执行的循环。这是脚本的一部份,该脚本扫描数据中的模式并进行相应的处理。每次awk将注意力转移到一条记录上时,就会执行{}中的句子(除非以BEGIN或END开头)。

要将键和值添加到链表linux中awk命令,请创建一个包含字段的变量(在本示例脚本中,我将其称为ARRAYlinux操作系统下载,即使不是很原汁原味,但很清楚),之后在方括弧中分配给它键,用等号(=)联接值。

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

在此句子中,第二个数组的内容($2)用作关键字,而当前记录($R)用作值。

asorti()函数

不仅字段之外,awk还具有一些基本函数,你可以将它们用作常见任务的快速简便的解决方案。GNUawk中引入的函数之一asorti()提供了键盘(索引)或值对字段进行排序的功能。

你只能在对字段进行填充后对其进行排序,这意味着此操作不能对每位新记录都触发,而只能在脚本的最后阶段进行。因此,awk提供了特殊的END关键字。与BEGIN相反,END句子仅在扫描了所有记录以后才触发一次。

将这种添加到你的脚本:

END {
    asorti(ARRAY,SARRAY);
    # get length
    j = length(SARRAY);
   
    for (i = 1; i <= j; i++) {
        printf("%s %sn", SARRAY[i],ARRAY[SARRAY[i]])
    }
}

asorti()函数获取ARRAY的内容,按索引对其进行排序,之后将结果装入名为SARRAY的新字段(我在本文中发明的任意名称,表示“排序的ARRAY”)。

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

最后,使用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;
}

尝试运行该脚本,便于在执行脚本时使用-vvar选项将其按第三数组排序:

$ ./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

修正

本文演示了怎样在纯GNUawk中对数据进行排序。你可以对脚本进行改进,便于对你有用,花一些时间在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 %sn", SARRAY[i],ARRAY[SARRAY[i]])
    }
}

via:

作者:SethKenlon选题:lujun9972译者:wxy校对:wxy

本文由LCTT原创编译deepin linux,Linux中国荣誉推出

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复