Каталогизация CD и DVD

Есть превосходный скрипт на unixforum, процитирую здесь:
#!/bin/bash
# (c) Alexander Polakov, 2005.
# (c) Ilya Portnov 2006

# В файле ~/.catalog_rc должно быть написано что-то вроде
# CDROM=/media/cdrom0 # точка монтирования CD
# DVDRW=/media/cdrom0 # точка монтирования DVD
# EJECT_CMD="eject"   # команда открытия лотка
# CLOSE_CMD="eject -t"# команда закрытия лотка
# DB="/mnt/ldata/cds" # директория, в которой будут храниться индексы
# DBFILE="/mnt/ldata/cd.table" # файл для таблицы свойств

# Для zsh можно сильно упростить использование скрипта, добавив в
# ~/.zshrc следующее:
# disknames()
# {
#   reply=($(ls /mnt/ldata/cds))
# }
# compctl -x "p[1]" -k "(new list show select search set setnew ls)" - "p[2] c[-1,new]" -k "(cd dvd)" - "p[2] c[-1,select]" -k "(adddate recdate owner place ttl)" - "p[2]" -K disknames - "p[3] c[-2,set]" -k "(adddate recdate owner place ttl)" -- cds

# Примеры вызова:
#
# cds new dvd
#         -- проиндексирует DVD, имя спросит
# cds new cd MyFirstCD
#         -- проиндексирует CD с именем 'MyFirstCD'
# cds show
#         -- покажет список всех проиндексированных дисков
# cds show My*CD
#         -- покажет список дисков с именами по маске 'My*CD'
# cds list
#         -- покажет список всех файлов на всех дисках
# cds list MyFirstCD
#         --- покажет список файлов на MyFirstCD
# cds set MyFirstCD recdate 29.01.06
#         -- установит свойство 'recdate' диска 'MyFirstCD' в значение '29.01.06'
# cds select recdate 29.01.06
#         -- покажет список дисков, у которых recdate=='29.01.06'
# cds ls \$1 \$2 \$5
#         -- покажет список всех дисков, для каждого выписывая имя, adddate и place
# cds search
#         -- спросит строку, которую будет искать в списке всех файлов на всех дисках
TMP=/tmp

if [ $# -lt 1 ]
then
	   cat <<EOF
Synopsis:
cds new <cd|dvd> [name] [noeject | tar] -- index new CD,
                              noeject - do not open tray,
                              tar - there are only few tar archives on the disk,
cds show [mask]            -- show a list of indexed CDs, matching to [mask],
cds list                   -- show a list of files on all indexed CDs,
cds list <name>            -- show a list of files on CD <name>,
cds set <name> <prop> <val>    -- set CD <name>'s <prop> to <val>,
cds setnew <name> <prop> <val> -- set CD <name>'s <prop> to <val>, if it was empty,
cds select [mask] <prop> <val> -- show a list of CDs, matching to [mask], where <prop>=<val>,
cds ls <prop prop...>      -- show a list of CDs with given props,
cds props [mask]           -- show all props for CDs matching [mask],
cds search [mask]          -- search for a string in list of files on CDs, matching to [mask]

Available props are: adddate, recdate, owner, place, ttl.
                    ( \$2       \$3     \$4    \$5   \$6 )

EOF
     exit 1
fi

new()
{
	# Checking config file...
	if [ -f ~/.catalog_rc ]
	then
		   . ~/.catalog_rc
	fi

  D=$(echo $DISK | tr a-z A-Z)
  case $DISK in
     cd) POINT=$CDROM ;;
    dvd) POINT=$DVDRW ;;
  esac

	echo -n "Put the $D into your drive, hit Return when done"
  read
  echo "Please wait, mounting $D..."
  if [ "x$OPT" != "xnoeject" ]
  then $CLOSE_CMD
  fi
  mount $POINT
  if [ -z $ID ]
  then echo -n "Please choose name for that $D: "
       read NAME
  else NAME=$ID
  fi
	echo -n "Please wait, indexing... "
  if [ "x$OPT" = 'xtar' ]
  then cat $(find $POINT -type f -and -not -name md5sums) | tar tf - | gzip > $DB/$NAME.$DISK
  else ls -lhAR $POINT | gzip > $DB/$NAME.$DISK
  fi
  CDT=$(date +"%d.%m.%Y")
  if egrep "^$NAME.$DISK" -q $DBFILE
  then sed -e "s|^$NAME.$DISK.*$|$NAME.$DISK\t$CDT\t$CDT|" -i $DBFILE
  else echo -e "$NAME.$DISK\t$CDT\t$CDT" >> $DBFILE
  fi
  echo -n "unmounting $D... "
  if [ "x$OPT" != "xnoeject" ]
  then umount $POINT
       $EJECT_CMD
  else umount $POINT
  fi
	echo "Ready"
	exit 0

}

search()
{
	  # Checking config file...
	if [ -f ~/.catalog_rc ]
	then
		. ~/.catalog_rc
	fi

  if [ -z "$OPT" ]
  then echo -n "Please enter the string to search: "
       read FILENAME
  else FILENAME=$OPT
  fi

  if [ -z "$ID" ]
  then ID='*'
  fi

  (for F in $DB/$ID
      do G=`basename $F`
      zgrep -i "$FILENAME" $F | sed -e "s=$CDROM=$G:=g" -e "s=$DVDRW=$G:=g" > $TMP/search.result
      if [ -s $TMP/search.result ]
      then echo $G:
           cat $TMP/search.result
           echo "============"
           echo
      fi
      done) | $PAGER
  rm -f $TMP/search.result
	exit 0

}

setprop()
{
	  # Checking config file...
	if [ -f ~/.catalog_rc ]
	then
		. ~/.catalog_rc
	fi

  cp $DBFILE $TMP/cd.db

  case $PROP in
    adddate) awk "\$1 ~ /^$ID\$/ {print \$1,\"$VAL\",\$3,\$4,\$5,\$6} \$1 !~/^$ID\$/ { print }" < $TMP/cd.db > $DBFILE ;;
    recdate) awk "\$1 ~ /^$ID\$/ {print \$1,\$2,\"$VAL\",\$4,\$5,\$6} \$1 !~/^$ID\$/ { print }" < $TMP/cd.db > $DBFILE ;;
      owner) awk "\$1 ~ /^$ID\$/ {print \$1,\$2,\$3,\"$VAL\",\$5,\$6} \$1 !~/^$ID\$/ { print }" < $TMP/cd.db > $DBFILE ;;
      place) awk "\$1 ~ /^$ID\$/ {print \$1,\$2,\$3,\$4,\"$VAL\",\$6} \$1 !~/^$ID\$/ { print }" < $TMP/cd.db > $DBFILE ;;
        ttl) awk "\$1 ~ /^$ID\$/ {print \$1,\$2,\$3,\$4,\$5,\"$VAL\"} \$1 !~/^$ID\$/ { print }" < $TMP/cd.db > $DBFILE ;;
  esac
  rm -f $TMP/cd.db

  exit 0
}

catprops()
{
  if [ -f ~/.catalog_rc ]
  then . ~/.catalog_rc
  fi

  egrep '^$ID' $DBFILE
  exit 0
}

srchprops()
{
  if [ -f ~/.catalog_rc ]
  then . ~/.catalog_rc
  fi

  if [ ! $ID ]
  then ID=".*"
  fi

  case $PROP in
    adddate) awk "(\$1 ~ /^$ID$/) && (\$2 ~ /^$VAL$/)" < $DBFILE > $TMP/search.result ;;
    recdate) awk "(\$1 ~ /^$ID$/) && (\$3 ~ /^$VAL$/)" < $DBFILE > $TMP/search.result ;;
      owner) awk "(\$1 ~ /^$ID$/) && (\$4 ~ /^$VAL$/)" < $DBFILE > $TMP/search.result ;;
      place) awk "(\$1 ~ /^$ID$/) && (\$5 ~ /^$VAL$/)" < $DBFILE > $TMP/search.result ;;
        ttl) awk "(\$1 ~ /^$ID$/) && (\$6 ~ /^$VAL$/)" < $DBFILE > $TMP/search.result ;;
  esac

  ( echo "Total: $(cat $TMP/search.result | wc -l) disks."
    cat $TMP/search.result) | $PAGER

  rm -f $TMP/search.result

  exit 0
}

list()
{

	# Checking config file...
	if [ -f ~/.catalog_rc ]
	then
		. ~/.catalog_rc
	fi

  if [ -z "$ID" ]
  then (for F in $DB/*
        do G=`basename $F`
           echo $G:
           zcat $F | sed -e"s=$CDROM=$G:=g" -e "s=$DVDRW=$G:=g" | sed -e"s=/mnt/cdrom=$G:=g"
           echo "=============="
           echo
        done) | $PAGER
  else (for F in $DB/$ID
        do B=`basename $F`
           zcat $F | sed -e "s=$CDROM=$B:=g" -e "s=$DVDRW=$B:=g" | sed -e"s=/mnt/cdrom=$B:=g"
           echo "=============="
           echo
        done) 2> /dev/null | $PAGER
  fi
  exit 0
}

lsprops()
{
  if [ -f ~/.catalog_rc ]
  then . ~/.catalog_rc
  fi

  awk "\$1 ~ /^$ID$/ { print $OPT}" < $DBFILE | $PAGER

  exit 0
}

show()
{
	# Checking config file...
	if [ -f ~/.catalog_rc ]
	then
		. ~/.catalog_rc
	fi

  if [ -z $ID ]
  then ID=*
  fi

  (cd $DB
   echo Total: `ls $ID | wc -l` disks;
   ls -lAh $ID | awk '{print $8 "\t" $5 "\t" $6 "\t" $7 "\t" }' | expand -t31,35,38,46,56)| $PAGER
  exit 0
}

# parse options
N=$#
ACTION=$1
DISK=cd

case $ACTION in
   new) DISK=$2
        ID=$3
        OPT=$4 ;;
  set)  ID=$2
        PROP=$3
        VAL=$4
        OPT=$5 ;;
  setnew)  ID=$2
        PROP=$3
        VAL=$4
        OPT=$5 ;;
 select)  if [ $4 ]
        then ID=$2
             PROP=$3
             VAL=$4
             OPT=$5
        else ID=
             PROP=$2
             VAL=$3
             OPT=$4
        fi ;;
  list) ID=$2
        OPT=$3 ;;
    ls) ID=$2
        OPT="$3 $4 $5 $6 $7 $8 $9" ;;
     *) ID=$2
        OPT=$3;;
esac

if [ ! $PAGER ]
then PAGER=less
fi

case $1 in
    new) new ;;
 search) search ;;
 select) srchprops ;;
   list) list ;;
   show) show ;;
    set) setprop ;;
  props) catprops ;;
     ls) lsprops ;;
esac

exit 0

Хороший скрипт. И работоспособен, если использовать фиксированную точку монтирования диска. Хотя и не слишком понимаю как работает, и, в частности, не понимаю откуда берётся в $ID имя файловой системы CD|DVD. Но пытаюсь пользоваться своей командой:
udevil mount /dev/sr0 && tree -h /media > `echo $( isoinfo -i /dev/sr0 -d | sed '/Volume id: /!d' | sed 's/Volume id: //g')`.list && udevil umount /dev/sr0 && eject
На некоторых дисках проходит, а на других, выдаёт ошибку:

bash: `echo $( isoinfo -i /dev/sr0 -d | sed '/Volume id: /!d' | sed 's/Volume id: //g')`.list: ambigous redirect

Перенес сообщение об ошибке из xterm вручную, потому что, если взять эту строку в двойные кавычки и скормить в echo с перенаправлением в файл, чтобы при помощи блокнота скопипастить, выдаётся другая ошибка:
bash: id': event not found

Можно ли Volume id извлечь более рационально ? Пытался заменить sed 's/Volume id: //g' на awk '{ print $2}' но там своя ошибка - любые знаки препинания awk воспринимает как новый столбец.

И ещё: можно ли сделать в моей команде редактирование будущего имени файла ?

UPD: Переделал.
nnnn=`udevil mount /dev/sr0 | grep Mounted | awk -F "at /media/" '{ print $2 }'` && tree -h /media > tmp && mv tmp "`echo $nnnn`_.list" && echo "Saved as $nnnn.list" && udevil umount /dev/sr0 && eject

Вопрос о строчном редакторе имени файла с каталогом открыт.
Не до конца понятно предназначение, если тэги из медиафайлов не вытаскивать и там к cddb для аудиодисков не обращаться. Кстати странно, что для работы с видеобазами и audio/cddb под линукс софта значительно меньше, чем под win. Из каталогизаторов на qt вспоминаю tellico и cdcat, и есть на java давно не поддерживаемый cddb-прокси JeFCo.jar.
WBR, eugenez // Debian:cli | Manjaro:Cinnamon | Arch:KDE | Kubuntu
 
Зарегистрироваться или войдите чтобы оставить сообщение.