Linux程序设计的CD唱片应用程序

!/bin/bash

非常简单的示例shell脚本,用于管理CD集合

这个程序是自由软件;您可以重新分配它并/或修改它。

我们还捕获了Ctrl-C,因此如果用户中断脚本,我们的临时文件将被删除。

menu_choice=””
current_cd=””
title_file=”title.cdb”//标题文件
tracks_file=”tracks.cdb”//跟踪文件
temp_file=/tmp/cdb.

//,
是表示的是当前进程的ID号
trap ‘rm -f $temp_file’ EXIT
//表示的是脚本接收到EXIT的信号时, trap执行删除临时文件的操作

现在我们定义我们的函数,以便从顶部执行的脚本可以找到。

//得到返回值
get_return() {
// 其中 c的作用是,把c后面的字符串停止输出
echo -e “Press return c”//任意键继续
read x
return 0
}

//询问是否确认
//返回正确为0,错误为1
//与C语言和c++语言不同
get_confirm() {
echo -e “Are you sure? c”
while true
do
read x
case “$x” in
y | yes | Y | Yes | YES )
return 0;;
n | no | N | No | NO )
echo
echo “Cancelled”
return 1;;
*) echo “Please enter yes or no” ;;
esac
done
}

在这里,我们来到主菜单函数set_menu_choice。

菜单的内容是动态变化的,如果一个CD条目添加了额外的选项。

被选中。注意,echo -e可能无法移植到某些shell中。

set_menu_choice() {

  clear//先清屏
  echo "Options :-"
  echo
  echo "   a) Add new CD"
  echo "   f) Find CD"
  echo "   c) Count the CDs and tracks in the catalog"
  if [ "$cdcatnum" != "" ]; then
    echo "   l) List tracks on $cdtitle"
    echo "   r) Remove $cdtitle"
    echo "   u) Update track information for $cdtitle"
  fi
  echo "   q) Quit"
  echo
  echo -e "Please enter choice then press return c"
  read menu_choice
  return

}

还有两个非常短的函数,insert_title和insert_track用于添加到数据库文件。

尽管有些人讨厌这样的一行程序,但它们有助于使其他功能更清晰。

它们后面是使用它们的较大的add_record_track函数。

这个函数使用模式匹配来确保不输入逗号(因为我们使用逗号)。

作为一个字段分隔符),以及算术运算来增加当前的曲目数量。

insert_title() {
echo >>title_file//给予它额外的参数
return
}

insert_track() {
echo >>tracks_file//给予它额外的参数
return
}

add_record_tracks() {
echo “Enter track information for this CD”
echo “When no more tracks enter q”
cdtrack=1
cdttitle=””
while [ “$cdttitle” != “q” ]
do

  echo -e "Track $cdtrack, track title? c"
  read tmp
  cdttitle=${tmp%%,*}
  //从tmp中拿出第一个参数
  //若是拿出最后一位参数为:${tmp%,*}

  if [ "$tmp" != "$cdttitle" ]; then
    echo "Sorry, no commas allowed"
    continue//这个是继续的意思,回到while重新执行
  fi
  if [ -n "$cdttitle" ] ; then//判断cdttitle是否为空
    if [ "$cdttitle" != "q" ]; then
      insert_track $cdcatnum,$cdtrack,$cdttitle
    fi
  else
    cdtrack=$((cdtrack-1))
  fi
cdtrack=$((cdtrack+1))

done
}

add_records函数允许新CD的主CD信息进入

add_records() {
# 提示初始信息。

echo -e “Enter catalog name c”
read tmp
cdcatnum=${tmp%%,*}

echo -e “Enter title c”
read tmp
cdtitle=${tmp%%,*}

echo -e “Enter type c”
read tmp
cdtype=${tmp%%,*}

echo -e “Enter artist/composer c”
read tmp
cdac=${tmp%%,*}

# 检查他们是否想输入信息。

echo About to add new entry
echo “cdcatnumcdtitle cdtypecdac”

#如果确认,则追加到标题文件。

if get_confirm ; then
insert_title cdcatnum,cdtitle,cdtype,cdac
add_record_tracks
else
remove_records
fi

return
}

find_cd函数在CD标题文件中搜索目录名文本,使用。

grep命令。我们需要知道字符串被找到的次数,但是grep只返回。

一个值告诉我们它是否匹配0次或多次。为了解决这个问题,我们储存了。

一个文件中的输出,每个匹配有一行,然后计算文件中的行数。

单词count命令,wc,在其输出中有空格,分隔行数,

文件中的单词和字符。我们使用(wcltemp_file)符号来提取。

来自输出的第一个参数设置linesfound变量。如果我们想要另一个,

后面的参数我们将使用set命令来设置shell的参数变量。

命令输出。

我们将IFS(内部字段分隔符)改为a(逗号),这样我们就可以将其分离。

用逗号分隔的字段。另一个命令被删除。

find_cd() {

      if [ "$1" = "n" ]; then
        asklist=n
      else
        asklist=y
      fi
      cdcatnum=""
      echo -e "Enter a string to search for in the CD titles c"
      read searchstr
      if [ "$searchstr" = "" ]; then
        return 0
      fi

  grep "$searchstr" $title_file > $temp_file


 set $(wc -l $temp_file)//使用其中的某个数据域
 inlinesfound=$1
  case "$linesfound" 
  0)    echo "Sorry, nothing found"
        get_return
        return 0
        ;;

  1)    ;;
  2)    echo "Sorry, not unique."
        echo "Found the following"
        cat $temp_file
        get_return
        return 0

esac

IFS=”,”
read cdcatnum cdtitle cdtype cdac < $temp_file
IFS=” “

if [ -z “$cdcatnum” ]; then
//判断cdcatnum是否为空(本身为0)

echo “Sorry, could not extract catalog field from $temp_file”
get_return
return 0
fi

  echo
  echo Catalog number: $cdcatnum
  echo Title: $cdtitle
  echo Type: $cdtype
  echo Artist/Composer: $cdac
  echo
  get_return

  if [ "$asklist" = "y" ]; then
    echo -e "View tracks for this CD? c"
      read x
    if [ "$x" = "y" ]; then
      echo
      list_tracks
      echo
    fi
  fi

return 1
}

update_cd允许我们重新输入CD的信息。注意我们搜索(grep)

行开始(^)美元cdcatnum后跟一个,,,我们需要包装

在{}中扩展$cdcatnum,我们可以搜索一个没有空格的。

号码和目录号。这个函数还使用{}来包含多个语句。

如果get_confirm返回true,将执行该操作。

update_cd() {

  if [ -z "$cdcatnum" ]; then
    echo "You must select a CD first"
    find_cd n
  fi
  if [ -n "$cdcatnum" ]; then
    echo "Current tracks are :-"
    list_tracks
    echo
    echo "This will re-enter the tracks for $cdtitle"
    get_confirm && {//  语句块,当get_confirm返回true时才会执行
      grep -v "^${cdcatnum}," $tracks_file > $temp_file//^表示的行首
      mv $temp_file $tracks_file
      echo
      add_record_tracks
    }

fi
return
}

count_cds为我们提供了数据库内容的快速计数。

count_cds() {

  set $(wc -l $title_file)
  num_titles=$1
  set $(wc -l $tracks_file)
  num_tracks=$1
  echo found $num_titles CDs, with a total of $num_tracks tracks
  get_return
  return

}

remove_records从数据库文件中删除条目,使用grep -v删除所有文件。

匹配字符串。注意,我们必须使用一个临时文件。

如果我们想这样做,

grep - v“^ $ # cdcatnum ” > title_file美元

$title_file将在grep之前由>输出重定向设置为空。

有执行的机会,所以grep会从一个空文件中读取。

remove_records() {

  if [ -z "$cdcatnum" ]; then
echo You must select a CD first
find_cd n
  fi
  if [ -n "$cdcatnum" ]; then

echo "You are about to delete $cdtitle"
get_confirm && {
  grep -v "^${cdcatnum}," $title_file > $temp_file
  mv $temp_file $title_file
  grep -v "^${cdcatnum}," $tracks_file > $temp_file
  mv $temp_file $tracks_file
  cdcatnum=""
  echo Entry removed
}
get_return

fi
return
}

List_tracks再次使用grep来提取我们想要的行,剪切来访问字段。

我们想要,然后更多的提供一个分页的输出。如果你考虑有多少行。

要重新实现这20多行代码,你会很感激的。

这是一个多么强大的工具。

list_tracks() {

  if [ "$cdcatnum" = "" ]; then
echo no CD selected yet
return
  else
grep "^${cdcatnum}," $tracks_file > $temp_file
num_tracks=$(wc -l $temp_file)
if [ "$num_tracks" = "0" ]; then
  echo no tracks found for $cdtitle
else { 
  echo
  echo "$cdtitle :-"
  echo 
  cut -f 2- -d , $temp_file 
  echo 
} | ${PAGER:-more}
fi

fi
get_return
return
}

现在已经定义了所有的函数,我们可以进入主例程。

开头的几行简单地将文件放入已知状态,然后我们调用菜单。

函数,set_menu_choice,并对输出进行操作。

当选择退出时,我们删除临时文件,写入消息并退出。

rm -f tempfileif[!ftitle_file ]; then
touch titlefilefiif[!ftracks_file ]; then
touch $tracks_file
fi

应用

clear
echo
echo
echo “Mini CD manager”
sleep 1

quit=n
while [ “quit!=y];dosetmenuchoicecasemenu_choice” in
a) add_records;;
r) remove_records;;
f) find_cd y;;
u) update_cd;;
c) count_cds;;
l) list_tracks;;
b)
echo
more $title_file
echo
get_return;;
q | Q ) quit=y;;
*) echo “Sorry, choice not recognized”;;
esac
done

Tidy up and leave

rm -f $temp_file
echo “Finished”

exit 0

技术不分国界
原文地址:https://www.cnblogs.com/angels-yaoyao/p/12443628.html