【问题标题】:How can I fix my bash script to find a random word from a dictionary?如何修复我的 bash 脚本以从字典中查找随机单词?
【发布时间】:2020-05-29 08:11:10
【问题描述】:

我正在学习 bash 脚本,但我一直在修复这个网站的一个练习:https://ryanstutorials.net/bash-scripting-tutorial/bash-variables.php#activities

任务是编写一个 bash 脚本以从字典中输出一个随机单词,其长度等于作为第一个命令行参数提供的数字。

我的想法是创建一个子字典,为每个单词分配一个数字行,从这些行中选择一个随机数并过滤输出,这适用于类似的更简单的脚本,但不适用于此。

这是我使用的代码:

  6 DIC='/usr/share/dict/words'
  7 SUBDIC=$( egrep '^.{'$1'}$' $DIC )
  8 
  9 MAX=$( $SUBDIC | wc -l )
 10 RANDRANGE=$((1 + RANDOM % $MAX))
 11 
 12 RWORD=$(nl "$SUBDIC" | grep "\b$RANDRANGE\b" | awk '{print $2}')
 13 
 14 echo "Random generated word from $DIC which is $1 characters long:" 
 15 echo $RWORD

这是我在输入“21”时遇到的错误:

bash script.sh 21
script.sh: line 9: counterintelligence's: command not found
script.sh: line 10: 1 + RANDOM % 0: division by 0 (error token is "0")
nl: 'counterintelligence'\''s'$'\n''electroencephalograms'$'\n''electroencephalograph': No such file or directory
Random generated word from /usr/share/dict/words which is 21 characters long:

我尝试在 bash 中将代码拆分成更小的部分,没有出现错误 (input=21):

egrep '^.{'21'}$' /usr/share/dict/words | wc -l
3

但一旦在脚本第 9 行和第 10 行出现错误。

你认为错误在哪里?

【问题讨论】:

  • $SUBDIC 中,您正在存储实际单词(egrep 命令的输出),但随后您尝试执行这些单词($( $SUBDIC) ...
  • 如果您有 GNU (Linux),请考虑 grep -E "^.{$1}$" /usr/share/dict/words |shuf -n1,如果运行 BSD/Mac,请考虑 grep -E "^.{$1}$" /usr/share/dict/words |sort -R |head -n1

标签: linux bash shell


【解决方案1】:

问题

  1. SUBDIC=$( egrep '^.{'$1'}$' $DIC ) 会将给定长度的所有单词存储在SUBDIC 变量中,因此它的内容现在类似于foo bar baz

  2. MAX=$( $SUBDIC | ... ) 将尝试运行命令foo bar baz,这显然是假的;它应该更像MAX=$(echo $SUBDIC | ... )

  3. MAX=$( ... | wc -l ) 将计算 ;使用上面提到的echo $SUBDIC 时,您将有多个单词,但都在一行中...

  4. RWORD=$(nl "$SUBDIC" | ...) 与上述相同的问题:只有一行(另请注意@armali 的回答 nl 需要文件或标准输入)

  5. RWORD=$(... | grep "\b$RANDRANGE\b" | ...) 可能匹配字典条目catch 22

  6. RWORD=$(... | awk '{print $2}') 可能不会处理包含空格的行

一个简单的解决方案

对所有可能的单词进行“随机排序”并取第一行就足够了:

  egrep "^.{$1}$" "${DIC}"  | sort -R | head -1

【讨论】:

    【解决方案2】:
    • MAX=$( $SUBDIC | wc -l ) - 管道用于连接命令的输出,而 $SUBDIC 不是命令;适当的语法是 MAX=$( <<<$SUBDIC wc -l )
    • nl "$SUBDIC" - nl 的参数必须是文件名,"$SUBDIC" 不是;适当的语法是 nl <<<"$SUBDIC"

    【讨论】:

    • 谢谢你,修复了保留其结构的脚本。
    【解决方案3】:

    这段代码可以做到。我的单词测试词典在文件file 中。最好先获取给定长度的所有单词,但将它们放在数组中,而不是放在 var 中。然后得到一个随机索引并回显它。

    dic=( $(sed -n "/^.\{$1\}$/p" file) )
    ind=$((0 + RANDOM % ${#dic[@]}))
    echo ${dic[$ind]}
    

    【讨论】:

      【解决方案4】:

      cat /usr/share/dict/american-english | head -n $RANDOM | tail -n 1

      $RANDOM - 每次引用时返回一个不同的随机数。 这个简单的行从提到的字典中输出随机单词。

      否则你可以按照umläute mentined:

      cat /usr/share/dict/american-english | sort -R | head -1

      【讨论】:

        猜你喜欢
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 2022-12-08
        • 2022-01-03
        • 2012-10-01
        • 1970-01-01
        • 2011-02-07
        • 2021-06-03
        相关资源
        最近更新 更多