要明确的是,你所询问的部分不是使用bash或任何其他shell的内容,因此如果你想学习在UNIX环境下正确的操作方式:shell是一个环境,用于创建/销毁文件和进程,并对工具进行顺序调用。如果你想使用强制性UNIX工具(即存在于每个UNIX系统上的工具)来完成类似的操作,则应该使用awk而非shell。唯一与shell有关的部分就是调用awk。
考虑到这一点,如果你想在"bash"中编写一个hangman程序,以下是一种使用任何shell中的任何awk进行提示/猜测的方法,适用于每个UNIX系统:
$ cat tst.awk
BEGIN {
secret = word
gsub(/./,"_",secret)
print "\nOutcome:", secret
printf "guess? "
}
{
guess = $0
while ( pos=index(word,guess) ) {
secret = substr(secret,1,pos-1) guess substr(secret,pos+1)
word = substr(word,1,pos-1) "_" substr(word,pos+1)
}
print "\nOutcome:", secret
if (word ~ /^_*$/) {
exit
}
printf "guess? "
}
现在,bash(或任何其他shell)部分只需:
$ awk -v word='abcdef' -f tst.awk
Outcome: ______
guess? a
Outcome: a_____
guess? e
Outcome: a___e_
guess? d
Outcome: a__de_
guess? f
Outcome: a__def
guess? b
Outcome: ab_def
guess? c
Outcome: abcdef
我决定编写一个完整的hangman shell脚本,为您生成5个或更多字母的单词供您猜测,因为这很有趣,所以这里是:
$ cat ./hangman.sh
declare -a words
trap 'printf "\nwords used:\n"; printf "%s\n" "${words[@]}"; exit' 0
prtwords() {
local dfltwordfile='/usr/share/dict/words'
{
if [[ -s "$dfltwordfile" ]]; then
cat "$dfltwordfile"
else
curl -s 'https://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-type=text/plain'
fi
} |
tr 'A-Z' 'a-z' |
grep -E '.{5}' |
shuf
}
guesschars() {
awk -v word="$1" '
BEGIN {
secret = origWord = word
gsub(/./,"_",secret)
print "\nOutcome:", secret
printf "guess? "
maxFailures = 6
}
NF {
guess = substr($1,1,1)
isFailure = 1
while ( pos=index(word,guess) ) {
isFailure = 0
secret = substr(secret,1,pos-1) guess substr(secret,pos+1)
word = substr(word,1,pos-1) "_" substr(word,pos+1)
}
numFailures += isFailure
print "\nOutcome:", secret
if ( (word ~ /^_*$/) || (numFailures == maxFailures) ) {
print "The word was", origWord
exit
}
printf "guess? "
}
'
}
exec 3</dev/tty || exec 3<&0
echo 'Hit interrupt to stop' >&2
while IFS= read -r word; do
words+=( "$word" )
guesschars "$word" <&3
echo '#####' >&2
done < <(prtwords)
exec 3<&-
.
$ ./hangman.sh
Hit interrupt to stop
Outcome: __________
guess? a
Outcome: _______a__
guess? e
Outcome: _e__e__a_e
guess? s
Outcome: _e__e__a_e
guess? t
Outcome: _e__e__ate
guess? r
Outcome: _e_re__ate
guess? c
Outcome: _e_rec_ate
guess? d
Outcome: de_rec_ate
guess? p
Outcome: deprec_ate
guess? i
Outcome: depreciate
The word was depreciate
Outcome: ______
guess?
words used:
depreciate
enrico
s///1
等中没有第0个匹配。就像从1开始的行号一样,匹配号也从1开始。所以,在调用sed之前为什么不先增加索引呢? - stevesliva