代码:
#!/bin/bash
word=$( sort -R $2 | head -1 | tr [a-z] [A-Z])
cache=$( echo $word | tr [A-Z] '_')
nb=$( echo $word | wc -m)
nbCar=$( echo $nb -1| bc)
echo "Mystery word: $cache ($nbCar letters)"
echo $word
echo "Enter a letter:"
read -n 1 letter
echo ""
pos=$( echo $word | grep -aob ${letter^^} | grep -oE '[0-9]+')
echo ${letter^^}
echo $pos
所以如何使用我的变量$pos
用读取的字母替换缓存'_'
example1:我的名字是yoyo
我读了
$pos = 0 2
cache = y_y_
example2:我的名字是yoyo
我读了
$pos = NULL
cache = ____
回显“未找到”
答案 0 :(得分:1)
您可以使用两种不同的方法:
在所需位置读取字符串
回显$ {word:$ pos:1}
您将在$ pos位置的单词中回显一个字符
echo $word | sed "s/./<The character that you want>/$pos"
“”非常重要,因为您要放置$ pos(只有'会失败)
由于您在$ pos中有多个职位,因此您必须一次迭代并更改一个职位。
有趣的链接
答案 1 :(得分:0)
假设$letter
包含“ y”,$cache
已设置为"____"
,pos
已设置为"0 2"
:
cache=$(echo $pos | tr ' ' '\n' |
{ while read pos
do pos=$(expr $pos + 1)
cache=$(echo $cache | sed -e 's/./'"$letter"'/'"$pos")
done
echo $cache
})
让我们检查一下值:
$ echo $cache
y_y_
$pos
替换end-of-line
的空格
字符。$pos
的每个值$cache
替换$letter
的第n个字符。$cache
被找到的字母更新了。此处用括号括起来,将while循环和最后一个回显放在同一子shell中,这样该回显不会丢失$cache
的值。
注意::我想说这种方法不是最好的方法,每次替换我都叫sed
。我们可以为此使用Bash内置函数/运算符。
答案 2 :(得分:0)
这里的意图似乎是创建一个游戏,通过显示猜出的字母的位置来揭示随机单词。问题中的示例代码采用的方法是从下划线字符串开始,然后用猜出的字母替换下划线。一种更简单的方法是用下划线替换未猜测的字母。这个纯Bash代码试图实现游戏:
#! /bin/bash
declare -r wordsfile=$2
# Read the list of words into an array
mapfile -t words <"$wordsfile"
# Select a random word from the array, and uppercase it
myword=${words[RANDOM%${#words[*]}]^^}
# Set a variable to hold the word with unknown letters replaced by underscores
guessed_word=${myword//?/_}
printf 'Mystery word: %s (%d letters)\n' "$guessed_word" ${#myword}
guessed_letters= # String containing letters guessed so far
while [[ $guessed_word != "$myword" ]] ; do
printf 'Enter a letter:'
read -r -n 1 letter
printf '\n'
guessed_letters+=${letter^}
# Make a glob pattern that matches everything except letters that
# have been guessed so far. E.g. 'AB' -> '[^AB]'.
other_letters_glob="[^$guessed_letters]"
# Replace everything except guessed letters in the word with underscores
guessed_word=${myword//$other_letters_glob/_}
printf 'Mystery word: %s\n' "$guessed_word"
done
代码是Shellcheck-clean,但没有错误或输入检查,即使对于这样的琐碎游戏也没有足够的反馈。
答案 3 :(得分:0)
对于“如何使用我的var $ pos我可以用读取的字母替换缓存'_'”,请尝试:
for p in $pos ; do
cache=${cache:0:p}${letter}${cache:p+1}
done
从某些评论看来,创建pos
列表可能存在问题。此代码应可靠地执行此操作:
pos=
for ((i=0; i<${#word}; i++)) ; do
[[ ${word:i:1} == "$letter" ]] && pos+=" $i"
done
如果pos
值是非空的,它将有一个前导空格字符,但这不会引起任何问题。最好为pos
使用数组,但这需要在代码的其他地方进行更改。
可以将letter
中的cache
设置为与word
中相同的位置,而无需完全存储位置:
ncache=
for ((i=0; i<${#word}; i++)) ; do
[[ ${word:i:1} == "$letter" ]] && ncache+=$letter || ncache+=${cache:i:1}
done
cache=$ncache