Рейтинговые книги
Читем онлайн Основы программирования в Linux - Нейл Мэтью

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 25 26 27 28 29 30 31 32 33 ... 200

 # Если получено подтверждение, добавляет данные в конец файла.

 # с заголовками

 if get_confirm ; then

  insert_title $cdcatnum, $cdtitle, $cdtype, $cdac

  add_record_tracks

 else

  remove_records

 fi

 return

}

7. Функция find_cd с помощью команды grep ищет текст с названием компакт-диска в файле с заголовочной информацией. Вам нужно знать, сколько раз была найдена строка, а команда grep только вернет значение, указывающее на то, что строка не была найдена или была найдена многократно. Для решения этой проблемы сохраните вывод в файл, отводящий по одной строке на каждое найденное совпадение, а затем сосчитайте количество строк в файле.

У команды счетчика слов, wc, в выводе есть пробельный символ, разделяющий количества строк, слов и символов в файле. Используйте синтаксическую запись $(wc -l $temp_file) для извлечения первого параметра в выводе и переноса его в переменную linesfound. Если бы вам был нужен другой следующий далее параметр, нужно было бы воспользоваться командой set для установки значений переменных-параметров оболочки из вывода команды.

Изменив значение переменной IFS (Internal Field Separator, внутренний разделитель полей) на запятую, вы сможете разделить поля, разграниченные запятыми. Альтернативный вариант — применить команду cut.

find_сd() {

 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)

 linesfound=$1

 case "$linesfound" in

  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

  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

}

8. Функция update_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 && {

   grep -v "^${cdcatnum}, " $tracks_file > $temp_file

   mv $temp_file $tracks_file

   echo

   add_record_tracks

  }

 fi

 return

}

9. Функция 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

}

10. Функция remove_records удаляет элементы из файлов базы данных с помощью команды grep -v, удаляющей все совпадающие строки. Учтите, что нужно применять временный файл.

Если вы попытаетесь применить команду:

grep -v "^$cdcatnum" > $title_file

файл $title_file станет пустым благодаря перенаправлению вывода > до того, как команда 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

}

11. Функция list_tracks снова использует команду grep для извлечения нужных вам строк, команду cut для доступа к отдельным полям и затем команду more для постраничного вывода. Если вы посмотрите, сколько строк на языке С займет повторная реализация этих 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

}

12. Теперь, когда все функции определены, можно вводить основную процедуру. Первые несколько строк просто приводят файлы в известное состояние; затем вы вызываете функцию формирования меню set_menu_choice и действуете в соответствии с ее выводом.

Если выбран вариант quit (завершение), вы удаляете временный файл, выводите сообщение и завершаете сценарий с успешным кодом завершения.

rm -f $temp_file

if [ ! -f $title_file ]; then

 touch $title_file

fi

if [ ! -f $tracks_file ]; then

 touch $tracks_file

fi

# Теперь непосредственно приложение

clear

echo

echo

echo "Mini CD manager" sleep 1

quit=n

while [ "$quit" != "y" ]; do

 set_menu_choice

 case "$menu_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

# Убираем и покидаем

rm -f $temp_file echo "Finished"

exit 0

Замечания, касающиеся приложения

Команда trap в начале сценария предназначена для перехвата нажатия пользователем комбинации клавиш <Ctrt>+<C>. Им может быть сигнал EXIT или INT, в зависимости от настроек терминала.

Существуют другие способы реализации выбора пункта меню, особенно конструкция select в оболочках bash и ksh (которая, тем не менее, не определена в стандарте X/Open). Она представляет собой специализированный селектор пунктов меню. Проверьте ее на практике, если ваш сценарий может позволить себе быть немного менее переносимым. Для передачи пользователям многострочной информации можно также воспользоваться встроенными документами.

Возможно, вы заметили, что нет проверки первичного ключа, когда создается новая запись; новый код просто игнорирует последующие названия с тем же кодом, но включает их дорожки в перечень первого названия:

1 First CD Track 1

2 First CD Track 2

1 Another CD

2 With the same CD key

Мы оставляем это и другие усовершенствования в расчете на ваше воображение и творческие способности, которые проявятся при корректировке вами программного кода в соответствии с требованиями GPL.

Резюме 

В этой главе вы увидели, что командная оболочка — это мощный язык программирования со своими функциональными возможностями. Ее способность легко вызывать программы и затем обрабатывать их результат делают оболочку идеальным средством для решения задач, включающих обработку текста и файлов.

1 ... 25 26 27 28 29 30 31 32 33 ... 200
На этой странице вы можете бесплатно читать книгу Основы программирования в Linux - Нейл Мэтью бесплатно.
Похожие на Основы программирования в Linux - Нейл Мэтью книги

Оставить комментарий