如何使用位置替换字母

时间:2018-10-18 15:35:17

标签: bash debian

代码:

#!/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 = ____

回显“未找到”

4 个答案:

答案 0 :(得分:1)

您可以使用两种不同的方法:

  1. 在所需位置读取字符串

    回显$ {word:$ pos:1}

您将在$ pos位置的单词中回显一个字符

  1. 在所需位置写入字符串

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_
  1. 在这里,用$pos替换end-of-line的空格 字符。
  2. 然后,while循环处理$pos的每个值
  3. 对于每个值,它用$cache替换$letter的第n个字符。
  4. 最后,$cache被找到的字母更新了。

Screenshot as proof

此处用括号括起来,将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