在飞机上用《sed与awk》消磨时间时,想起网友以前提过的一个问题:
1 按指定列的长度排序
1.1 问题
这个网友有以下格式的词库(in.txt):
w=我
bm=标
ceq=陈
wm=我们
nnyl=努
wm,=我们
djh=大家好
tdmd=他们
tzm=同志们
tzm,=同志们
djhnv=大家好
ppaa=平平安安
tzmdv=同志们
ppaa,=平平安安
wrmfw=为人民服务
gzrzf=工作认真负责
他希望对词库按照这样的规则排序:将=看作列分隔符,先按照第二列的长度排序,再按第一列的长度排序,再按第二列编码排序,再按第一列编码排序。例如,上面一段示例的排序结果是:
w=我
bm=标
ceq=陈
nnyl=努
wm=我们
wm,=我们
tdmd=他们
djh=大家好
tzm=同志们
tzm,=同志们
djhnv=大家好
tzmdv=同志们
ppaa=平平安安
ppaa,=平平安安
wrmfw=为人民服务
gzrzf=工作认真负责
我说用excel可以实现。网友说excel太慢了,而且不能支持几十万行的词组。让我们能不能用awk解决这个问题。
1.2 awk简介
awk是一个神奇的文本处理工具。它按照我们的命令逐行处理输入的文本。我们把命令写在一个脚本文件中,例如在一个叫作test.awk的文件中写一行命令:
{print $2}
然后念动咒语,让awk执行我们的命令:
awk -F= -f test.awk in.txt
我们就会得到以下输出:
我
标
陈
我们
努
我们
大家好
他们
同志们
同志们
大家好
平平安安
同志们
平平安安
为人民服务
工作认真负责
awk的特点是它把文本看作数据列表,每行数据包括由分隔符分隔的多个数据项。默认的分隔符是空格或制表符。我们可以在命令行上用-F 参数指定分隔符,例如“-F=”命令awk用“=”作为分隔符。 -f 参数指定要执行的脚本文件。
再看看命令。命令被放在{}中,在{}前面可以指定命令的作用范围,即对哪些行执行这个命令。如果没有指定作用范围,就对所有行执行命令。 awk用$1表示每行的第一个数据项,用$2表示第二个数据项,依此类推。$0可以用来引用整行文本。"print $2"就是打印第二项,所以我们就看到了上面的结果。
让我们下达一个新命令,将test.awk修改为:
{print length($2) "\t" $2}
再念动咒语:
awk -F= -f test.awk in.txt
我们这次得到了:
1 我
1 标
1 陈
2 我们
1 努
2 我们
3 大家好
2 他们
3 同志们
3 同志们
3 大家好
4 平平安安
3 同志们
4 平平安安
5 为人民服务
6 工作认真负责
length函数可以求字符串的长度,length($2)就是第二列字符串的长度。"\t"是制表符。我们检查一下第一列的数字是不是中文词组的长度?
awk还能支持类似于C语言的printf函数,这样我们能精确地控制输出。例如将test.awk修改为:
{printf("%02d%02d\t%s\t%s\n", length($2), length($1), $2, $1)}
如果读者熟悉printf函数,应该很容易看懂这行命令。这次我们得到的输出是:
0101 我 w
0102 标 bm
0103 陈 ceq
0202 我们 wm
0104 努 nnyl
0203 我们 wm,
0303 大家好 djh
0204 他们 tdmd
0303 同志们 tzm
0304 同志们 tzm,
0305 大家好 djhnv
0404 平平安安 ppaa
0305 同志们 tzmdv
0405 平平安安 ppaa,
0505 为人民服务 wrmfw
0605 工作认真负责 gzrzf
我们在原来的文本前面加了一列,这列的每一项是4个数字,前两个数字是中文词组的长度,后面两个数字是编码的长度。
1.3 神奇时刻
我们再准备一个命令文件output.awk,内容是:
{print $3"="$2}
读者能看懂这个命令的含义吗?然后我们念动一长串咒语:
awk -F= -f test.awk in.txt|sort|awk -f output.awk>output.txt
我们得到了输出文件output.txt,它的内容是:
w=我
bm=标
ceq=陈
nnyl=努
wm=我们
wm,=我们
tdmd=他们
djh=大家好
tzm=同志们
tzm,=同志们
djhnv=大家好
tzmdv=同志们
ppaa=平平安安
ppaa,=平平安安
wrmfw=为人民服务
gzrzf=工作认真负责
这就是我们需要的结果。“awk -F= -f test.awk in.txt”的意思前面已经说过了。它的输出通过管道“|”被传给sort。 sort对输入排序后又通过管道传给“awk -f output.awk”。命令“print $3"="$2”打印了输入的第三列和第二列并用“=”分隔这两列。最后,我们将“awk -f output.awk”的输出重定向到output.txt,就得到了上面的结果。
1.4 在windows上执行
我把本文用到的工具和例子放到了我的主页上(下载)。读者解压后,在命令行进入sortit目录,执行:
awk -F= -f test.awk in.txt|lsort|awk -f output.awk>output.txt
就可以得到上面描述的结果。在windows上为了不与windows的sort冲突,我把sort程序更名为lsort。
2 结束语
awk是一个文本处理的中级魔法,学习过这种魔法的人就可以驾驭它。有一本介绍这种魔法的书叫做《sed与awk》。我读了前面两章,然后通过查找书末的快速参考和几次尝试,解决了一个文本处理的小问题。
这本魔法书,除了awk外,还介绍一个叫做sed的中级魔法。awk和sed都是处理文本流的工具,文本流过它们,按照我们的命令变成我们想要的形状。如果说awk是专门处理文本列表的编程语言,sed就是把很多编辑命令预先写好在一个叫作脚本的文件里,然后对一个或很多文件执行这个脚本。 sed擅长大量的查找和替换。综合使用这两个魔法,再加上sort、grep等初级魔法的帮助,我们可以轻松完成很多文本处理工作。
分享到:
相关推荐
AWK是一种编程语言,专门用于文本处理和数据提取。GAWK是AWK语言的一个GNU版本,通常简称为awk。本书为用户提供了一种指南,帮助他们有效地使用GAWK进行编程。 描述中提到的“GAWK说明;GNU awk教程”进一步确认了...
AWK是一种优秀的文本处理工具,它在Linux和UNIX环境下广泛用于数据分析和文本处理。AWK语言由Aho, Weinberger, 和 Kernighan三位创建者的名字首字母而得名。它允许用户在命令行模式下或通过编写程序脚本来分析和处理...
7. **文本处理示例**:通过一系列实用案例展示如何运用awk解决各种实际问题,如数据统计分析、日志文件管理等。 8. **高级主题**:探讨awk编程中的一些高级技术,例如多文件处理、网络通信功能的实现等。 9. **最佳...
awk 是一个强大的文本...当遇到文本处理问题时,可以遵循这样的顺序:首先尝试使用 shell 工具,如果不够,再使用 awk,如果 awk 仍无法满足需求,那么可以考虑使用 C 语言或 C++ 这样的编程语言来实现更复杂的逻辑。
根据提供的文档信息,我们可以从中提炼出与Linux系统中`awk`和`sed`相关的几个重要知识点,特别是关于如何使用这两种工具来处理文本文件的具体应用场景。接下来,我们将详细地阐述这些知识点。 ### 5.6:awk高级...
第十一章:提供多种awk版本的快速参考,包括POSIX awk和其他几个版本。 第十二章:详细介绍了如何使用sed和awk构建功能齐全的应用程序。 第十三章:提供了一些常用的脚本示例,以供读者参考和学习。 附录A是sed的...
awk 具有以下几个特点,使其 Became Very Popular 在数据处理和文本处理领域: * 使用直译器(Interpreter),不需要编译 * 变量无类型之分(Typeless) * 可使用文字当数组的下标(Associative Array) * 具有内建...
awk 不仅仅是一个命令,更是一种样式扫描和处理语言,它具有类似数据库的功能,但处理的是普通文本文件,而非特殊格式的数据库文件。awk 在处理文本数据时,可以进行模式匹配、数据提取、转换和报告生成,它融合了流...
为了更好地理解AWK,下面通过几个具体的例子来展示如何编写AWK程序。 ##### 示例1:打印文件中每一行的第一个字段 ```awk awk '{print $1}' file.txt ``` 这里,`$1`表示当前行的第一个字段。 ##### 示例2:统计...
GNU Awk,又称GAWK,是一种强大的文本处理工具,它允许用户以一种简单而有效的方式在文本文件中执行复杂的模式匹配、数据提取、数据转换和报告生成。《GAWK: Effective AWK Programming - GNU Awk编程经典》是一本...
《sed与awk(第二版)》是一本深入探讨Linux/Unix系统中两个强大的文本处理工具——sed和awk的书籍。这两个工具在系统管理和自动化任务中起着至关重要的作用,尤其对于数据处理和文本操作有着无可比拟的优势。在本书中...
操作由一个或多个命令、函数、表达式组成,通常包含以下几个部分: - **变量或数组赋值**:例如 `var = "value"` 或 `array[index] = value`。 - **输出命令**:如 `print` 和 `printf` 用于输出数据。 - **内置...
标题明确指出该PDF文档是关于“sed”与“awk”两个文本处理工具的详细介绍。sed是一个流编辑器,用于对文本数据执行基本的文本转换,而awk是一个编程语言,专门用于文本和数据的提取、处理和报告。描述部分强调了这...
- **数字标志和打印标志p**:数字标志用于指定处理输入行中的第几个匹配项,打印标志p用于打印替换后的行。 - **写标志w和忽略大小写标志i**:写标志w将被替换的行写入指定文件,而忽略大小写标志i使得搜索不区分大...
本文将深入探讨几个常用的命令,包括sed、awk、grep和tr,它们都是强大的文本处理工具,尤其在处理大量文本数据时非常有用。 首先,让我们聚焦于AWK命令。AWK是由Aho、Weinberger和Kernighan三位计算机科学家开发的...
在awk脚本编程中,经常会遇到一些初学者的困惑,这里我们将详细解答标题和描述中提到的几个常见问题。 1. `awk '{code}1'` 中的 "1" 是干什么的? 在awk中,"1"是一个特殊的行为,它等价于默认的动作`{print}`。awk...
总结,awk作为强大的文本分析工具,其精髓在于模式匹配和动作执行的结合,通过理解和实践,我们可以利用awk解决各种文本处理问题,提升我们的工作效率。希望这个学习笔记能帮助你更好地理解和运用awk。