损坏:带有增量计数器的 For 循环中的 Elif
Broken: Elif in For loop with increment counter
我写了一个简短的脚本来为 macintalk 中的音节合成生成格式化的字符串。我想每 20 个音节插入一个静音,所以我写了一个 for 循环,其中有一个存储在临时文件中的计数器和一个嵌套的 elif 语句,该语句应该在每次计数器达到 20 时添加一个静音命令。然后计数器在达到后重置20.
出于某种原因我无法预测,elif 仅在第一次发现条件为真时才被访问。换句话说:计数器第一次达到 20 时,它会插入静音命令,重置并继续循环。计数器第二次达到 20 时,elif 未被访问并继续增长,直到 $k 达到其最大值。
有人知道为什么这段代码不起作用吗?
编辑 ** 根据大众要求,这里有一段稍长的摘录 =)
如果您想尝试重现,这里是文件的链接:
syllables_phncode.txt
cbsyllindx.txt
# Load Syllables
echo ''
echo 'Opening Syllable Transcription for Victoria'
echo ''
syllfile=./syllables_phncode.txt
syllables=$(cat $syllfile)
syllarray=()
counter=0;
# Create Indexed Array of Phonological Code for Syllables
for k in $syllables
do
echo $counter
echo $k
syllarray[counter]=$k
counter=$(($counter + 1));
done
# Load syllable index for stimulus stream
indxfile=./cbsyllindx.txt
indx=$(cat $indxfile)
stream=''
tempfile=count.tmp
echo 0 > $tempfile
echo '====================================================================================='
echo 'Counter Balanced Stimulus Order (Indexed by Syllables in Alphabetical Order)'
echo '====================================================================================='
echo $indx
echo '====================================================================================='
echo ''
echo 'Creating counterbalanced stimulus stream string with proper Macintalk formatting'
echo ''
for k in $indx
do
counter=$[$(cat $tempfile) + 1]
echo $counter > $tempfile
if [ $k -eq 0 ]; then
stream=$stream'@_'${syllarray[k]}
elif [ $counter -eq 20 ]; then
echo Adding Silence after syllable: ${syllarray[k]}
stream=$stream'_'${syllarray[k]}'[[ slnc 20 ]]'
echo 0 > $tempfile
else
stream=$stream'_'${syllarray[k]}
fi
done
unlink $tempfile
echo '------------------------------------------------------'
echo 'Printing Stream to Screen'
echo '------------------------------------------------------'
echo $stream
这是由此脚本创建的字符串:
_tUW_dAE_rOW_pIY_gOW_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE_pIY_gOW[[slnc20]]_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE_tUW_dAE_rOW_bUW_dOW_pAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_tUW_dAE_rOW_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_bUW_dOW_pAE_tUW_dAE_rOW_bUW_dOW_pAE_tUW_dAE_rOW_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_tUW_dAE_rOW@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_tUW_dAE_rOW_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_bUW_dOW_pAE_tUW_dAE_rOW_pIY_gOW_lAE@_bIY_kUW_tIY_pIY_gOW_lAE_bUW_dOW_pAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE_tUW_dAE_rOW@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW_bUW_dOW_pAE@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_bUW_dOW_pAE@_bIY_kUW_tIY_tUW_dAE_rOW_bUW_dOW_pAE_tUW_dAE_rOW_pIY_gOW_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE
你的问题是当 $counter
等于 20
时你点击了 $k -eq 0
检查但是你无论如何增加计数器然后一旦你通过 20
你可以再也不会打了。
您可以通过在脚本顶部添加 set -x
和 运行 并查看输出来看到这一点。
您不希望if/else进行不相关的检查它有这个问题。
您可能需要更像这样的东西作为循环体。
if [ $k -eq 0 ]; then
stream=${stream}@
fi
stream=${stream}_${syllarray[k]}
if [ $counter -eq 20 ]; then
stream=$stream'[[ slnc 20 ]]'
fi
这使关注点分开。
您也根本不需要(如评论中所示)此处的临时文件。 (除了处理读取文件的子 shell 外,您没有任何子 shell。)
您也可以使用 $(< file)
来避免 $(cat file)
子 shell。
您还应该始终使用 $((...))
而不是 $[...]
。
我写了一个简短的脚本来为 macintalk 中的音节合成生成格式化的字符串。我想每 20 个音节插入一个静音,所以我写了一个 for 循环,其中有一个存储在临时文件中的计数器和一个嵌套的 elif 语句,该语句应该在每次计数器达到 20 时添加一个静音命令。然后计数器在达到后重置20.
出于某种原因我无法预测,elif 仅在第一次发现条件为真时才被访问。换句话说:计数器第一次达到 20 时,它会插入静音命令,重置并继续循环。计数器第二次达到 20 时,elif 未被访问并继续增长,直到 $k 达到其最大值。
有人知道为什么这段代码不起作用吗?
编辑 ** 根据大众要求,这里有一段稍长的摘录 =)
如果您想尝试重现,这里是文件的链接: syllables_phncode.txt cbsyllindx.txt
# Load Syllables
echo ''
echo 'Opening Syllable Transcription for Victoria'
echo ''
syllfile=./syllables_phncode.txt
syllables=$(cat $syllfile)
syllarray=()
counter=0;
# Create Indexed Array of Phonological Code for Syllables
for k in $syllables
do
echo $counter
echo $k
syllarray[counter]=$k
counter=$(($counter + 1));
done
# Load syllable index for stimulus stream
indxfile=./cbsyllindx.txt
indx=$(cat $indxfile)
stream=''
tempfile=count.tmp
echo 0 > $tempfile
echo '====================================================================================='
echo 'Counter Balanced Stimulus Order (Indexed by Syllables in Alphabetical Order)'
echo '====================================================================================='
echo $indx
echo '====================================================================================='
echo ''
echo 'Creating counterbalanced stimulus stream string with proper Macintalk formatting'
echo ''
for k in $indx
do
counter=$[$(cat $tempfile) + 1]
echo $counter > $tempfile
if [ $k -eq 0 ]; then
stream=$stream'@_'${syllarray[k]}
elif [ $counter -eq 20 ]; then
echo Adding Silence after syllable: ${syllarray[k]}
stream=$stream'_'${syllarray[k]}'[[ slnc 20 ]]'
echo 0 > $tempfile
else
stream=$stream'_'${syllarray[k]}
fi
done
unlink $tempfile
echo '------------------------------------------------------'
echo 'Printing Stream to Screen'
echo '------------------------------------------------------'
echo $stream
这是由此脚本创建的字符串:
_tUW_dAE_rOW_pIY_gOW_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE_pIY_gOW[[slnc20]]_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE_tUW_dAE_rOW_bUW_dOW_pAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_tUW_dAE_rOW_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_bUW_dOW_pAE_tUW_dAE_rOW_bUW_dOW_pAE_tUW_dAE_rOW_bUW_dOW_pAE@_bIY_kUW_tIY_pIY_gOW_lAE_bUW_dOW_pAE@_bIY_kUW_tIY_tUW_dAE_rOW@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_tUW_dAE_rOW_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_bUW_dOW_pAE_tUW_dAE_rOW_pIY_gOW_lAE@_bIY_kUW_tIY_pIY_gOW_lAE_bUW_dOW_pAE_tUW_dAE_rOW@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE_tUW_dAE_rOW@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW@_bIY_kUW_tIY_pIY_gOW_lAE_tUW_dAE_rOW_bUW_dOW_pAE@_bIY_kUW_tIY_bUW_dOW_pAE_pIY_gOW_lAE@_bIY_kUW_tIY_bUW_dOW_pAE@_bIY_kUW_tIY_tUW_dAE_rOW_bUW_dOW_pAE_tUW_dAE_rOW_pIY_gOW_lAE@_bIY_kUW_tIY_tUW_dAE_rOW_pIY_gOW_lAE_bUW_dOW_pAE
你的问题是当 $counter
等于 20
时你点击了 $k -eq 0
检查但是你无论如何增加计数器然后一旦你通过 20
你可以再也不会打了。
您可以通过在脚本顶部添加 set -x
和 运行 并查看输出来看到这一点。
您不希望if/else进行不相关的检查它有这个问题。
您可能需要更像这样的东西作为循环体。
if [ $k -eq 0 ]; then
stream=${stream}@
fi
stream=${stream}_${syllarray[k]}
if [ $counter -eq 20 ]; then
stream=$stream'[[ slnc 20 ]]'
fi
这使关注点分开。
您也根本不需要(如评论中所示)此处的临时文件。 (除了处理读取文件的子 shell 外,您没有任何子 shell。)
您也可以使用 $(< file)
来避免 $(cat file)
子 shell。
您还应该始终使用 $((...))
而不是 $[...]
。