本文共 1674 字,大约阅读时间需要 5 分钟。
今天在地磁쌔 낭.textContentYunsongWang在尝试解决LeetCode的“192 Word frequency”问题时遇到了一个关于Bash脚本的挑战。为了统计文件中单词的频率,初次写法遇到了一些问题。通过仔细分析和修正,最终找到了解决方案。下面详细记录这一过程。
本文将分步骤介绍如何编写一个Bash脚本解决问题,包括代码解析和优化。
目标与要求理解首先明确问题的核心:结合给定的文本文件,统计每个单词的出现频率,并按降序输出结果。文件中的单词仅由小写字母组成,之间由任意数量的空格分隔。但最初的脚本在实际运行中遇到了意外问题。
初步代码尝试与错误分析初次编写脚本时,代码结构大致如下:
#!/bin/bash# 统计单词频率并输出结果# 文本文件路径:words.txtdeclare -A map=()cat words.txt | while read linedo for word in $line do if [ -z "${map[$word]}" ]; then map[$word]=1 else map[$word]++ fi donedone < words.txt
运行脚本后,却发现结果不正确。进一步调试发现,问题出在while read line
的处理方式上。原因是Bash中的管道操作会在子shell中执行,而变量map
是在子shell中的临时副本。因此,在主shell中的map
数组未能得到正确更新,导致统计结果偏差。
while
循环而避免使用管道。这样,循环内部的处理逻辑能够直接作用于主shell中的map
数组。修改后的代码如下:#!/bin/bash# 统计单词频率并按降序输出# 文本文件路径:words.txtdeclare -A map=()while read linedo for word in $line do if [ -z "${map[$word]}" ]; then map[$word]=1 else map[$word]++ fi done done < words.txt
修改的关键点为:
cat
命令,而直接在while
循环中读取每行。如何实现正确的单词处理在读取文件的过程中,read line
会自动处理换行符。在分割单词时,可以使用tr ' ' '\n'
和sort
命令结合使用,但根据题目要求单词由小写字母组成且默认由空格分隔,不需要额外分隔处理。如果有多个空格,每个单词依然会被正确识别。
最高频率排序处理在输出阶段,可以通过对map
数组的键(单词)进行双重循环,从高到低输出。虽然Bash本身没有内置对数组按值排序的命令,但可以通过查找帮助组件(如compgen
)实现自定义排序方式。
当前脚本的正确结果示例假设输入文件words.txt
内容如下:
the day is sunny the thethe sunny is is
运行修正后的脚本,预期输出应为:
the 4is 3sunny 2day 1
最终,该问题的解决方案通过谨慎对待变量作用域和脚本结构,确保了统计结果的准确性。
转载地址:http://sfxlz.baihongyu.com/