我有这个文本文件:
worked
working
works
tested
tests
find
found
它包含一百万个没有空格的单词。它可能包含 Unicode 字符。
最长的单词是“working”:
awk '{print length, $0}' test.txt | sort -nr | head -1
7 working
我需要创建二元组、三元组(最多 7 列)
w,wo,wor,work,worke,worked,
w,wo,wor,work,worki,workin,working
w,wo,wor,work,works,,
t,te,tes,test,teste,tested,
t,te,tes,test,tests,,
f,fi,fin,find,,,,
f,fo,fou,foun,found,,
最好使用 awk(因为它很快)
一种直接的方法是:
在GNU Awk 5.3.0、mawk 1.3.4 20240819 和The One True Awk版本 20240728 上进行了测试。
如果您事先不知道字符串的最大长度,您可以使用:
如果您已经知道输入字符串的最大长度,则使用任何 awk(至少用于英语字符输入):
否则,采用两遍方法首先计算最大长度:
有了以上内容,我
length()
在循环开始前调用一次,因此 awk 不会在每次循环迭代时调用它,$0
在循环外部填充以避免 awk$0
在每次循环迭代时重新拆分和/或重新构建,$maxLen = $maxLen
仅在循环后使用,在每个输入行中创建最多 1 次空字段,并且因此它具有可移植性、速度快,并且适用于任何大小的输入文件。
@tripleee 在评论中指出,使用 unicode 字符时,上述脚本在 MacOS 上的输出不正确。MacOS 上的默认 awk 漏洞百出,而且我没有 Mac 可以测试,所以我不打算调查这个问题,但以下是我从上面第二个脚本中看到的结果,给出了 @tripleee 的输入,并在 cygwin 上使用 gawk 5.3.0 进行测试
LC_ALL='en_US.UTF-8'
:以下是它
-b
的作用(摘自gawk 手册):一种使用 Unicode 安全方法
ruby
(max=7-1
:从零开始,length-1
:尾随换行符)。$_
保存行,通过以下方式启用-n
输出
数据
Awk 不能很好地处理 Unicode 组合序列。也许可以使用 Perl 来方便地替代。
以下是使用越南语随机字符串进行的简短测试,其中使用了很多重音符号。
nawk
以下是此输入的行为演示:这是一个快速而粗糙的 Perl 实现:
这里用一个更熟悉的英语(嗯,借用词)来进行演示。
如果不明显的话,Perl 知道U+0301是一个组合字符,应该以图形方式与前面的基本字符连接,因此就正则表达式而言,将生成的群集视为单个字符(或更确切地说是字素)
\X
。因为 Awk 没有这方面的知识,所以它不能这样做。(也许也可以参见Wikipedia 上的Unicode 等价性。 )如果您确实想要二元组和三元组,而不是特定长度的前缀,这也很容易。