我有一个包含行的文件。
我如何编写一个脚本来查找并打印出文件中的每个单词(每行一个单词)。
然后查找并打印出文件中出现次数最多的单词(区分大小写)以及该单词出现的次数。
答案1
shell 一行代码:
cat file.txt | sed -r 's/[[:space:]]+/\n/g' | sed '/^$/d' | sort | uniq -c | sort -n | tail -n1
在统计单词之前删除标点符号,并将单词变为小写(英文):
cat file.txt | tr 'A-Z' 'a-z' | sed 's/--/ /g' | sed 's/[^a-z ]//g' | tr -s '[[:space:]]' '\n' | sort | uniq -c | sort -n | tail -n1
答案2
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
此命令执行以下操作:
- 用空格替换所有非字母数字字符。
- 所有换行符也转换为空格。
- 将所有多个空格缩减为一个空格
- 所有空格现在都转换为换行符。每个单词占一行。
- 将所有单词翻译为小写,以避免“Hello”和“hello”成为不同的单词
- 文本排序
- 计数并删除相等的线
- 按相反顺序排序以统计最常用的单词
- 为每个单词添加行号,以便了解单词在整体中的位置
例如,如果我想分析第一个 Linus Torvald 消息:
从:[电子邮件保护](Linus Benedict Torvalds) 新闻组:comp.os.minix 主题:您最想在 minix 中看到什么?摘要:针对我的新操作系统的小调查 消息 ID:<[电子邮件保护]> 日期:1991 年 8 月 25 日 20:57:08 GMT 组织:赫尔辛基大学
大家好,使用 minix 的用户们——
我正在为 386(486) AT 克隆机开发一个(免费)操作系统(只是业余爱好,不会像 gnu 那样庞大和专业)。这个计划从四月份就开始酝酿,现在正准备就绪。我希望得到大家对 minix 的喜好和厌恶的反馈,因为我的操作系统与它有些相似(文件系统的物理布局相同(出于实际原因)等)。
我目前已经移植了 bash(1.08) 和 gcc(1.40),一切似乎都运行正常。这意味着我将在几个月内得到一些实用的东西,我想知道大多数人想要什么功能。欢迎提出任何建议,但我不会承诺我会实现它们
答案3
#!/bin/bash
cat /dev/stdin
printf "\n"
sort | uniq -c | sort -nr
这个简单的脚本将充当词频计数器,只需使用sort
和uniq
并将它们连接在一起即可。首先,它从stdin
使用中打印cat
以显示输入。然后它打印一个换行符。最后,它对进行排序stdin
,使用计算唯一单词的数量uniq -c
,然后再次对列表进行排序,但使用 n 和 r 选项按数字顺序排列列表并反转列表,以便最常用的单词首先出现。由于它从标准输入流读取,因此可以这样调用它:script < inputfile
。
答案4
#!/bin/bash
file=$1
declare -A count
for word in $(< "$file"); do
echo $word
(( count[$word]++ ))
done
max=0
for word in "${!count[@]}"; do
if (( ${count[$word]} > $max )); then
max=${count[$word]}
max_word=$word
fi
done
echo "most seen word: '$max_word', seen $max times"
笔记:
$(<file)
是 bash 的简写$(cat file)
——它返回文件的内容- 因为
$(<file)
本身不是双引号,所以 shell 会将其拆分为单词,然后循环for
会对这些单词进行迭代。 - 您需要 bash 版本 4 才能使用关联数组
<opinion>
我不知道为什么人们抱怨 perl 语法丑陋:你知道如何在 bash 中处理数组吗?</opinion>