4

基本的に 6 つの異なる応答 (はい、いいえ、たぶん、わかりにくい、ありそうもない、不明) を持つ魔法の 8 ボールのような bash スクリプトを作成しようとしています。重要なのは、一度応答が与えられると、すべての応答が与えられるまで再度与えてはならないということです。

これが私がこれまでに持っているものです:

#!/bin/bash
echo "Ask and you shall receive your fortune: "
n=$((RANDOM*6/32767))
while [`grep $n temp | wc awk '{print$3}'` -eq 0]; do
   n=$((RANDOM*6/32767))
done
grep -v $n temp > temp2
mv temp2 temp

基本的に、一時ファイルの異なる行に 6 つの応答がすべてあります。応答が与えられると、その応答のない新しいファイル (temp2) を作成し、それを一時にコピーするようにループを構築しようとしています。次に、一時ファイルが空になると、最初から続行されます。

現在の内部ループが間違っていること、および外部ループが必要であることは非常に肯定的ですが、これにはかなり慣れていないため、行き詰まっています。

どんな助けでも大歓迎です。

4

3 に答える 3

1

次のようなことを試してください:

#!/bin/bash

shuffle() {
   local i tmp size max rand

   # $RANDOM % (i+1) is biased because of the limited range of $RANDOM
   # Compensate by using a range which is a multiple of the array size.
   size=${#array[*]}
   max=$(( 32768 / size * size ))

   for ((i=size-1; i>0; i--)); do
      while (( (rand=$RANDOM) >= max )); do :; done
      rand=$(( rand % (i+1) ))
      tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
   done
}

array=( 'Yes' 'No' 'Maybe' 'Hard to tell' 'Unknown' 'Unlikely' )

shuffle
for var in "${array[@]}"
do
  echo -n "Ask a question: "
  read q
  echo "${var}"
done
于 2012-12-15T03:00:45.877 に答える
1

最初のアプローチに従うスクリプトを作成しました(一時ファイルを使用):

#!/bin/bash

# Make a copy of temp, so you don't have to recreate the file every time you run this script
TEMP_FILE=$(tempfile)
cp temp $TEMP_FILE

# You know this from start, the file contains 6 possible answers, if need to add more in future, change this for the line count of the file
TOTAL_LINES=6

echo "Ask and you shall receive your fortune: "
# Dummy reading of the char, adds a pause to the script and involves the user interaction
read

# Conversely to what you stated, you don't need an extra loop, with one is enough
# just change the condition to count the line number of the TEMP file 
while [ $TOTAL_LINES -gt 0 ]; do
    # You need to add 1 so the answer ranges from 1 to 6 instead of 0 to 5
    N=$((RANDOM*$TOTAL_LINES/32767 + 1))

    # This prints the answer (grab the first N lines with head then remove anything above the Nth line with tail)
    head -n $N < $TEMP_FILE | tail -n 1

    # Get a new file deleting the $N line and store it in a temp2 file
    TEMP_FILE_2=$(tempfile)
    head -n $(( $N - 1 )) < $TEMP_FILE > $TEMP_FILE_2
    tail -n $(( $TOTAL_LINES - $N )) < $TEMP_FILE >> $TEMP_FILE_2
    mv $TEMP_FILE_2 $TEMP_FILE

    echo "Ask and you shall receive your fortune: " 
    read

    # Get the total lines of TEMP (use cut to delete the file name from the wc output, you only need the number)
    TOTAL_LINES=$(wc -l $TEMP_FILE | cut -d" " -f1)
done
于 2012-12-15T03:27:41.503 に答える
0
$ man shuf

SHUF(1)                                                           User Commands

NAME
       shuf - generate random permutations

SYNOPSIS
       shuf [OPTION]... [FILE]
       shuf -e [OPTION]... [ARG]...
       shuf -i LO-HI [OPTION]...

DESCRIPTION
       Write a random permutation of the input lines to standard output.

さらに多くのことが続きます。自分のマシンで読むことができます:)

于 2012-12-15T03:53:51.360 に答える