需要命令使用 grep 查找文件中唯一单词的数量
尝试使用 grep 以及 uniq 和 sort,但需要找到一种仅使用 grep 和 wc 命令的方法。这是我能够做到的两种方法,但我需要仅使用 grep ..
$ grep -oE '\w+' 'file.txt' | sort | uniq | wc -l
$ grep -oE '\w+' 'file.txt' > temp.txt && awk '!seen[$0]++' temp.txt | wc -l
输入文件示例:
one two three four five
two four one six
eight three seven five
输出:唯一字数:8
是否可以首先使用 grep -oE ‘\w+’ file.txt 命令提取单词,然后对每个单词执行 grep 到一个空文件,如果 grep 找不到该文件中存在的单词,则将单词附加到文件中.这样只有那些在新文件中找不到的单词才会被附加到它吗?可以使用 grep 来做到这一点吗?
9
3 个回答
3
既然你grep
有,-o
我假设它也有-P
和-z
:
grep -zPo '(?s)(\b\w+\b)(?!.*\b\1\b)' file.txt |
grep -zc ^
- 使用
-z
makegrep
将整个文件视为单个“行”(因为其中不应有空值) - 用于
-P
启用 Perl 兼容的正则表达式 (PCRE),允许环视断言 (?s)
– 告诉 PCRE.
也应该匹配换行符- 使用负向先行
(?!
…)
查找每个单词的最终出现位置(即单词后面没有跟任何单词)
\b\w+\b
并\b\1\b
排除部分单词
- 我们使用前瞻,以便前瞻文本不会被匹配消耗,并且可以在查找更多最终单词时重复使用
- 用于
-o
在自己的“行”上输出每个匹配项(因为-z
,空值被用作行结束字符) - 获取生成的唯一单词列表并输出“行”数
这对于较大的文件来说会非常慢。
6
-
1我现在正在思考该脚本的作用。根据 GNU grep 手册页有关
-P
“此选项与 -z (–null-data) 选项结合时是实验性的”,您知道上面的任何内容在这种情况下是否脆弱吗?
– -
1@EdMorton 鉴于 RE 遭受灾难性的回溯,脆弱性是其最不重要的问题
– -
1@EdMorton regex101 对于 3500 个单词输入达到 40M 步,并在 4000 个单词时超时,远远超出了这个范围,这可能会中断
– -
1好吧,OP只是问是否可以完成,而不是是否可以稳健、可移植、高效、可靠等完成,所以在我看来,这是一个很好的答案:-)。
– -
是的,对于任何大尺寸的输入,仅使用
sort -u
就更加稳健
–
|
由于 awk 也被标记,因此一种仅使用(几乎任何)的方法awk
,返回关联数组的长度,其中索引是单词。
% awk '{for(i=1;i<=NF;i++){A[$i]++}} END{print length(A)}' file
8
测试用
- GNU awk 3.1.8/4.2.1/5.3.0
- 诺克 20221215
- 原始 awk 20121220
- 莫克 20240123
0
|
你想要做的事情用 justgrep
或grep
+是不可能的wc
(除非你使用 GNUgrep
及其扩展和每个警告)。
鉴于此,如果您确实只想使用一种工具,则使用 GNU Awk 进行多字符处理RS
并假设一个由空格分隔的“单词”文件作为输入:
$ awk -v RS='\\s+' '{unq[$0]} END{print "unique word count:", length(unq)}' file.txt
unique word count: 8
或使用正则表达式来识别“单词”:
$ awk -v RS='\\w+' 'RT{unq[RT]} END{print "unique word count:", length(unq)}' file.txt
unique word count: 8
0
|
–
–
–
–
sort | uniq
=sort -u
和 2)grep -oE '\w+' 'file.txt' > temp.txt && awk '!seen[$0]++' temp.txt
=grep -oE '\w+' 'file.txt' | awk '!seen[$0]++'
。–
|