我在采访中遇到了一个问题
Shell脚本,用于显示文件和目录中每个单词的频率
A
- A1
- File1.txt
- File2.txt
-A2
- FileA21.txt
-A3
- FileA31.txt
- FileA32.txt
B
-B1
- FileB11.txt
- FileB12.txt
- FileB13.txt
-B2
-FileB21.txt
Run Code Online (Sandbox Code Playgroud)
我相信通过理解目录A和B是两个单独的目录来理解这个问题,其中A1,A2和A3是A的子目录,B1和B2是B的子目录.所以我这样回答.
Find . ‘\(-name “A” –and –name “B”\)’ –type f –exec cat ‘{}’ \; | awk ‘{c[$1]++} END {for (i in c) print i, c[i]}’
Run Code Online (Sandbox Code Playgroud)
但我仍然得到一个反馈,上面的脚本不够好.给定的脚本有什么问题?
主要限制是脚本假设每行只有一个单词。c[$1]++只是增加每行第一个字段的出现次数。
这个问题没有提到任何关于一行中的单词数,所以我认为这不是意图 - 你需要遍历一行中的每个单词。另外,空行怎么办?如果是空行,$1则将是空字符串,因此您的脚本最终将计算“空”单词(它会很高兴地显示为输出的一部分)。
在 awk 中,一行中的字段数存储在内置变量中NF;因此,很容易编写代码来循环遍历单词并增加相应的计数(并且它具有隐式忽略没有单词的行的良好副作用)。
所以,我会做这样的事情:
find . -type f -exec cat '{}' \; | awk '{ for (i = 1; i <= NF; i++) w[$i]++ } END { for (i in w) printf("%-10s %10d\n", i, w[i]) }'
Run Code Online (Sandbox Code Playgroud)
为了简洁起见,我删除了参数 to 中的目录名称约束find(1),并使其更加通用。
这(可能)是您的解决方案的主要问题,但问题(故意)含糊不清,并且还有很多事情需要讨论:
FWIW,永远记住,你在面试中的成功不是二元是/否。它不像:哎呀,你不能做 X,所以我要拒绝你。或者:哎呀,回答错误,你就出局了。比答案更重要的是实现这一目标的过程,以及您是否意识到 (a) 您所做的假设;(b) 您的解决方案的局限性。上面的问题显示了考虑边缘情况的能力、澄清假设和要求的能力等,这比获得“正确的”脚本更重要(并且可能不存在“正确的脚本”这样的东西)。