当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 8 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : shell下听写单词脚本(改进版)
帖子发表于 : 2011-03-30 13:32 

注册: 2009-07-01 22:04
帖子: 919
送出感谢: 0 次
接收感谢: 13
stardict可以收藏单词到dic.txt文件,利用这个文件和wave发音文件,写了个英语单词听写脚本,主要是练习略微复杂一点的写法,选项多细节也增多。
修正一些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


_________________
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。


最后由 fnan 编辑于 2011-04-05 22:51,总共编辑了 2 次

页首
 用户资料  
 
2 楼 
 文章标题 : Re: shell下听写单词脚本
帖子发表于 : 2011-03-30 13:35 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 274
只看到lz的bash还不错。
其他看不出。没空。


_________________
● 鸣学


页首
 用户资料  
 
3 楼 
 文章标题 : Re: shell下听写单词脚本(改进版)
帖子发表于 : 2011-04-05 22:52 

注册: 2009-07-01 22:04
帖子: 919
送出感谢: 0 次
接收感谢: 13
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
}


_________________
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。


页首
 用户资料  
 
4 楼 
 文章标题 : Re: shell下听写单词脚本(改进版)
帖子发表于 : 2011-05-11 15:57 

注册: 2009-07-01 22:04
帖子: 919
送出感谢: 0 次
接收感谢: 13
最近在原星际wave文件中加入了牛津的美式女声,由于格式问题aplay指令不能用了,作了一点改变:
aplay -q $vl_w& 改为 mplayer $vl_w &>/dev/null&
一共四句要改。


_________________
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。


页首
 用户资料  
 
5 楼 
 文章标题 : Re: shell下听写单词脚本(改进版)
帖子发表于 : 2011-06-24 14:44 

注册: 2008-10-31 22:12
帖子: 6546
系统: 践兔
送出感谢: 18
接收感谢: 25
espeak xxx


_________________
代码:
] ls -ld //


页首
 用户资料  
 
6 楼 
 文章标题 : Re: shell下听写单词脚本(改进版)
帖子发表于 : 2011-06-25 5:03 

注册: 2009-07-01 22:04
帖子: 919
送出感谢: 0 次
接收感谢: 13
真人语音,不是机器语音。


_________________
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。


页首
 用户资料  
 
7 楼 
 文章标题 : Re: shell下听写单词脚本(改进版)
帖子发表于 : 2011-07-12 18:42 

注册: 2011-06-27 18:06
帖子: 3
送出感谢: 0 次
接收感谢: 0 次
楼主强大! :em11 :em11


页首
 用户资料  
 
8 楼 
 文章标题 : Re: shell下听写单词脚本(改进版)
帖子发表于 : 2011-07-12 19:51 
头像

注册: 2006-02-28 3:11
帖子: 2470
送出感谢: 0 次
接收感谢: 0 次
等待神的perl版


_________________
一梦三年,
松风依旧,
萝月何曾老.


灵幽听微, 谁观玉颜?
灼灼春华, 绿叶含丹.


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 8 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译