首页 > 解决方案 > 用于替换和遍历的 Bash 脚本循环

问题描述

所以我试图弄清楚一个旧考试的问题是什么意思,我对一两个部分有点困惑。

#!/bin/bash
awk   '{$0 = tolower($0)
      gsub(/[,.?;:#!\(\)]/),"",$0)
      for(a=1;a<=NF;a++)
      b[$a]++}
      END print b[a],a}'
sort -sk2

这是我的解释:

我认为最后四行是我的主要问题。也只是我还是那个问题中有额外的}?

提前致谢。

标签: bashshellunix

解决方案


循环的for格式很奇怪。这里又是适当的缩进:

    for(a=1; a<=NF; a++)
        b[$a]++

换句话说,我们循环遍历字段位置;对于每一个,关联数组中的计数b都会增加。所以如果当前输入线是

foo bar poo bar baz

脚本会做

b["foo"]++  # a is 1; $a is $1
b["bar"]++
b["poo"]++
b["bar"]++
b["baz"]++

所以现在b包含一组标记作为键,每个标记出现的次数作为它们各自的值。换句话说,这会收集输入中每个单词的字数。

标点符号的大小写折叠和删除使输入标准化,以便

Word word word, word!

将算作“单词”出现四次,而不是大写版本、未修饰的范式和末尾附加标点符号的各一次。它稍微扭曲了例如应该正确大写的单词,并将其合并为仅通过大写来区分的同形异义词(例如china瓷器与China the country。)

END块仅在所有输入行都已用完时才执行,因此b完全加载了来自所有输入行的所有输入字,以及它们的最终计数。(虽然这里END实际上没有有效的块,因为缺少后面的左大括号END;这是一个致命的语法错误。没有一个右大括号太多,缺少一个非可选的左大括号。)


推荐阅读