shell下听写单词脚本(改进版)
发表于 : 2011-03-30 13:32
stardict可以收藏单词到dic.txt文件,利用这个文件和wave发音文件,写了个英语单词听写脚本,主要是练习略微复杂一点的写法,选项多细节也增多。
修正一些bug, 增加功能:
修正一些bug, 增加功能:
代码: 全选
#!/bin/bash
#begin
#{
export env_file_fifo="fifo$$"
export env_word_file
export env_pts=$(tty)
vg_echo="\n -f 单词文本\n 设定单词文本。\n\n
-d wav文件地址\n 设定wav文件夹地址。\n\n
-r\n 删除配置文件。\n\n
-h\n 帮助。\n\n
【【在听写模式下直接输入:】】\n\n
数字-数字(x-y)\n听写第x组到第y组。\n\n
g数字 (gx)\n每组x个单词。\n\n
s数字 (sx)\n从第x组开始听写。\n\n
00 \n配置写入磁盘并退出。\n\n
ENTER\n单击输入键重复发音。\n\n
e数字 (ex)\n错x次显示单词。\n\n
-cs\n查询词义『然后关闭或最小化stardict窗口,可按ALT+F4 或ALT+F9』\n\n
-drw\n删除当前单词文本中重复单词合为一个。\n\n
-utl\n把当前文本的大写字母改为小写字母。\n\n
-dwww\n删除当前文本中没有wave文件的单词,注意必须先在听写模式下出现过的词才能删除!\n\n
-h\n帮助\n\n"
vg_configuration_file=$0
vg_configuration_file=".${vg_configuration_file#./}.confg"
if [[ $# -eq 0 && ! -f ~/$vg_configuration_file ]];then
echo
echo "请先输入选项: $0 -f 单词文本 -d wav文件夹地址 [-h 『帮助』] "
echo
exit 1
fi
if [[ $# -ne 0 ]];then
while getopts ":f:d:rh" optname
do
case "$optname" in
"h")
echo -e $vg_echo|more
echo
exit 0
;;
"f")
env_word_file=$OPTARG
echo "单词文本=$env_word_file"
;;
"d")
vg_wave_directory=$OPTARG
echo "wav文件地址=$vg_wave_directory"
;;
"r")
echo "删除配置文件?y/n"
read -n1 vg_read
if [[ $vg_read = "y" ]];then
echo
if [[ -f ~/$vg_configuration_file ]];then
rm ~/$vg_configuration_file && echo "已删除$vg_configuration_file配置文件。"
else
echo "无配置文件。"
fi
exit 0
fi
;;
"?")
echo "未知选项? "$OPTARG
exit 1
;;
":")
echo "选项 "$OPTARG" 缺参数!"
exit 1
;;
"*")
echo "发生未知错误!"
exit 1
;;
esac
done
fi
if [[ ! -f ~/$vg_configuration_file ]];then
if [[ -z $vg_wave_directory ]];then
echo "缺wave文件夹参数!"
exit 1
fi
if [[ -z $env_word_file ]];then
echo "缺单词文本参数!"
exit 1
fi
else
if [[ -z $env_word_file ]];then
env_word_file=`sed '1q;d' ~/$vg_configuration_file`
fi
if [[ -z $vg_wave_directory ]];then
vg_wave_directory=`sed '2q;d' ~/$vg_configuration_file`
fi
fi
if [[ ! -f $env_word_file ]];then
echo "单词文本不存在!"
exit 1
elif (! head $env_word_file|grep -q '[a-zA-Z]');then
echo "单词文本为空!"
exit 1
elif [[ ! -d $vg_wave_directory ]];then
echo "wave文件夹不存在!"
exit 1
fi
#}
function f_delete_repeat_word
{
awk '{print $1 " " NR|"sort -k1,1"}' $env_word_file|awk 'BEGIN{n = 0}
{if (vl_2 == $1) {n++;a[n] = $2}; vl_2 = $1}
END{if (n != 0)
{print "\n检察出" n "个重复词."|"cat > $env_pts"}
else
{print "\n没有重复词。"|"cat > $env_pts";exit 1};
n2 = 0;
while (getline vl_l < ENVIRON[ "env_word_file" ])
{
n2++
for (i in a)
{
o = "p"
if (a[i] == n2)
{
o = "np"
break
};
};
if (o == "p")
print vl_l;
}
}' > "tmp$$"
if [[ $? -eq 0 ]];then
mv "tmp$$" $env_word_file
echo -e "\033[7m已写入$env_word_file文本.\033[0m"
else
rm "tmp$$" #已加上缺少的指令。
return 1
fi
}
function f_delete_without_wave_file_word
{
echo $vg_wwf_word|awk '{vl_wn = split($0,al_w," ")}
END{print "将删除" vl_wn "个无wave文件的单词。"|"cat > $env_pts"; n = 0; while (getline vl_l < ENVIRON[ "env_word_file" ])
{
n++
o = "p"
for (i in al_w)
{
if (vl_l == al_w[i])
{
delete al_w[i];
o = "np";
break
};
};
if (o == "p")
{
print vl_l
};
}
}' > "tmp$$"
if [[ $? -eq 0 ]];then
mv "tmp$$" $env_word_file
echo -e "\033[7m已在$env_word_file文本中删除单词。\033[0m"
else
return 1
fi
}
function f_get_without_wave_file_word
{
vg_wwf_word="$vg_wwf_word $1"
vg_wwf_word=$(echo $vg_wwf_word|xargs -n1|sort -u|xargs)
}
function f_get_group_count_and_word_number
{
if [[ ! -f ~/$vg_configuration_file ]];then
vg_group_word_number=100
else
vg_group_word_number=$(sed '3q;d' ~/$vg_configuration_file)
fi
if [[ $vg_group_word_number -gt $vg_file_word_number || -z $vg_group_word_number ]];then
vg_group_word_number=$vg_file_word_number
fi
vg_group_count=$(($vg_file_word_number/$vg_group_word_number))
if [[ $(($vg_file_word_number%$vg_group_word_number)) -ne 0 ]];then
((vg_group_count++))
fi
}
function f_get_group_range
{
f_get_group_count_and_word_number
if [[ -f ~/$vg_configuration_file ]];then
vg_first_group=`sed '4q;d' ~/$vg_configuration_file`
vg_last_group=`sed '5q;d' ~/$vg_configuration_file`
vg_group_sequence=`sed '6q;d' ~/$vg_configuration_file`
vg_error_number=`sed '7q;d' ~/$vg_configuration_file`
else
vg_first_group=1
vg_last_group=$vg_group_count
vg_group_sequence=1
vg_error_number=3
fi
}
function f_make_configure_file
{
echo "$env_word_file" > ~/$vg_configuration_file
echo "$vg_wave_directory" >> ~/$vg_configuration_file
echo "$vg_group_word_number" >> ~/$vg_configuration_file
echo "$vg_first_group" >> ~/$vg_configuration_file
echo "$vg_last_group" >> ~/$vg_configuration_file
echo "$vg_group_sequence" >> ~/$vg_configuration_file
echo "$vg_error_number" >> ~/$vg_configuration_file
}
function f_check_groups
{
if [[ $vg_first_group -gt $vg_group_count ]];then
vg_first_group=$vg_group_count
fi
if [[ -z $vg_first_group ]];then
vg_first_group=1
fi
if [[ $vg_last_group -gt $vg_group_count ]];then
vg_last_group=$vg_group_count
fi
if [[ -z $vg_last_group ]];then
vg_last_group=$vg_group_count
fi
if [[ $vg_group_sequence -gt $vg_last_group ]];then
vg_group_sequence=$vg_last_group
fi
if [[ -z $vg_group_sequence || $vg_group_sequence -le 0 ]];then
vg_group_sequence=1
fi
if [[ $vg_group_sequence -lt $vg_first_group ]];then
vg_group_sequence=$vg_first_group
fi
if [[ -z $vg_error_number || $vg_error_number -le 0 ]];then
vg_error_number=1
fi
f_make_configure_file
}
function f_get_configure
{
vg_file_word_number=`wc -w < $env_word_file`
f_get_group_range
f_check_groups
echo '共有'${vg_file_word_number}'个单词,每组'${vg_group_word_number}'个,共'${vg_group_count}'组,练习'${vg_first_group}'-'${vg_last_group}'组,第'${vg_group_sequence}'组开始,错'$vg_error_number'次显示单词。'
}
function f_get_group_words
{
local vl_command
local vl_first_word
local vl_last_word
declare -i vl_l
local vl_n
local vl_w
declare -i vl_r
if [[ $vg_group_count -eq 1 ]];then
vl_command='1,$p'
else
vl_first_word=$((($vg_group_sequence-1)*$vg_group_word_number+1))
if [[ $(($vg_group_sequence*$vg_group_word_number)) -ge $vg_file_word_number ]];then
vl_last_word='$'
else
vl_last_word=$(($vg_group_sequence*$vg_group_word_number))
fi
vl_command=$vl_first_word','$vl_last_word'p'
fi
ag_words=($(sed -n $vl_command ~/$env_word_file))
vl_l=${#ag_words[@]}
vl_n=0
while [[ $vl_n -lt $vl_l ]];do
vl_r=$((($RANDOM$(date +%N))%$vl_l))
vl_w=${ag_words[$vl_n]}
ag_words[vl_n]=${ag_words[$vl_r]}
ag_words[vl_r]=$vl_w
((vl_n++))
done
}
function f_consult_word
{
stardict ${ag_words[vl_n]} &>/dev/null&
local vl_pid=$(echo $! )
while read vl_order < $env_file_fifo;do
if [[ $vl_order == "quit" ]];then
kill $vl_pid&
break
fi
done
rm $env_file_fifo
aplay -q $vl_w&
}
function f_MAIN
{
f_get_configure
vg_read=1
local vl_n2
local vl_n3
local vl_w
local vl_l
vg_read=
((vg_group_sequence--))
while [[ $vg_read != "00" ]];do
((vg_group_sequence++))
if [[ $vg_group_sequence -gt $vg_last_group ]];then
vg_group_sequence=$(($vg_first_group))
fi
f_get_group_words
echo "第$vg_group_sequence 组"
vl_n=0
vl_n3=0
while [[ $vl_n -le $((${#ag_words[@]} - 1)) ]];do
vg_read=
vl_w=${ag_words[vl_n]}
vl_w=$vg_wave_directory${vl_w:0:1}'/'${vl_w}'.wav'
if [[ -f $vl_w ]];then
aplay -q $vl_w&
vl_n3=0
else
echo "-无${ag_words[vl_n]}的wave文件。"
f_get_without_wave_file_word ${ag_words[vl_n]}
((vl_n++))
((vl_n3++))
if [[ $vl_n -eq ${#ag_words[@]} ]];then
vl_n=0
if [[ $vl_n3 -eq ${#ag_words[@]} ]];then
vl_n3=0
echo -e "\033[31m整组单词无wave文件,启动自动删除!\033[0m"
f_delete_without_wave_file_word
if [[ $? -eq 0 ]];then
f_check_groups
vg_repeat_main="y"
return
else
exit 1
fi
fi
fi
continue
fi
vl_n2=0
while [[ $vg_read != ${ag_words[vl_n]} ]];do
echo -n "单词$(($vl_n+1))》 "
read vg_read
if (grep -q '[0-9]-[0-9]' <<<$vg_read);then
vg_first_group=${vg_read%%-*}
vg_last_group=${vg_read##*-}
f_check_groups
vg_repeat_main="y"
return
elif [[ $vg_read = "00" ]];then
f_make_configure_file
exit 0
elif [[ -z $vg_read ]];then
aplay -q $vl_w&
elif (grep -E -q 'g[0-9]+' <<<$vg_read);then
vg_group_word_number=${vg_read##*g}
if [[ $vg_group_word_number -gt $vg_file_word_number ]];then
vg_group_word_number=$vg_file_word_number
elif [[ $vg_group_word_number -le 0 ]];then
vg_group_word_number=1
fi
f_make_configure_file
vg_repeat_main="y"
return
elif (grep -E -q 's[0-9]+' <<<$vg_read);then
vg_group_sequence=${vg_read##*s}
f_check_groups
vg_repeat_main="y"
return
elif (grep -E -q 'e[0-9]+' <<<$vg_read);then
vg_error_number=${vg_read##*e}
f_check_groups
vg_repeat_main="y"
return
elif (grep -qe '-cs' <<<$vg_read);then
mkfifo $env_file_fifo
f_consult_word&
read -p "按ENTER键继续:"
echo "quit" > $env_file_fifo
elif (grep -qe '-drw' <<<$vg_read);then
f_delete_repeat_word
if [[ $? -eq 0 ]];then
f_check_groups
vg_repeat_main="y"
return
fi
elif (grep -qe '-utl' <<<$vg_read);then
sed -i 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' $env_word_file
echo -e "\033[7m$env_word_file文本的大写字母已改为小写字母。\033[0m"
vg_repeat_main="y"
return
elif (grep -qe '-dwww' <<<$vg_read);then
if [[ ! -z $vg_wwf_word ]];then
f_delete_without_wave_file_word
if [[ $? -eq 0 ]];then
f_check_groups
vg_repeat_main="y"
return
else
exit 1
fi
else
echo "未出现无wave文件的单词!"
fi
elif (grep -qe '-h' <<<$vg_read );then
clear
echo -e $vg_echo|more
elif [[ $vg_read != ${ag_words[vl_n]} ]];then
vl_l=${#vg_read}
((vl_n2++))
aplay -q $vl_w&
if [[ $vl_n2 -eq $vg_error_number ]];then
echo -e "\033[33;47m${ag_words[vl_n]}\033[0m"
vl_n2=0
else
for ((i=0;i<=$vl_l;i++));do
if [[ ${vg_read:$i:1} = ${ag_words[vl_n]:$i:1} ]];then
echo -n ${vg_read:$i:1}
else
echo -ne "\033[31m${vg_read:$i:1}\033[0m"
fi
done
fi
echo
fi
done
((vl_n++))
done
done
}
f_MAIN
while [[ $vg_repeat_main = "y" ]];do
f_MAIN
done
exit 0