Не могу заставить этот код работать - PullRequest
0 голосов
/ 01 апреля 2011

Я пишу сценарий оболочки bash, который использует регистр с тремя вариантами:

  1. Если пользователь вводит "change -r txt doc *", расширение файла изменяется в подкаталоге.
  2. Если пользователь вводит "change -n -r doc", он должен переименовывать файлы, заканчивающиеся на.-R или.-N (это переименует все файлы в текущем каталоге с именем * .-r как *.doc)
  3. Если пользователь ничего не вводит, как в «change txt doc *», он просто меняет расширение файла в текущем каталоге.

Вот код, который я создал дляэто (последние два варианта, я не уверен, как реализовать):

#!/bin/bash

case $1 in 
 -r)
  export currectFolder=`pwd`
  for i in $(find . -iname "*.$2"); do 
   export path=$(readlink -f $i)
   export folder=`dirname $path`
   export name=`basename $path .$2` 
   cd $folder
   mv $name.$2 $name.$3
   cd $currectFolder
  done
  ;;
 -n) 
  echo "-n"
  ;;
 *)
  echo "all"
esac

Может кто-нибудь исправить это для меня?Или, по крайней мере, скажите мне, где я иду не так?

1 Ответ

2 голосов
/ 02 апреля 2011

То, что вы должны освежить в памяти - это подстановки строк. Все виды на самом деле. Баш очень хорошо с ними. Страница 105 (рецепт 5.18) поваренной книги Bash отлично подходит для этого.

#!/bin/bash

# Make it more flexible for improving command line parsing later
SWITCH=$1
EXTENSIONSRC=$2
EXTENSIONTGT=$3

# Match different cases for the only allowed switch (other than file extensions)
case $SWITCH in
 -r|--)
  # If it's not -r we limit the find to the current directory
  [[ "x$SWITCH" == "x-r" ]] || DONTRECURSE="-maxdepth 1"
  # Files in current folder with particular pattern (and subfolders when -r)
  find . $DONTRECURSE -iname "*.$EXTENSIONSRC"|while read fname; do
    # We use a while to allow for file names with embedded blank spaces
    # Get canonical name of the item into CFNAME
    CFNAME=$(readlink -f "$fname")
    # Strip extension through string substitution
    NOEXT_CFNAME="${CFNAME%.$EXTENSIONSRC}"
    # Skip renaming if target exists. This can happen due to collisions
    # with case-insensitive matching ...
    if [[ -f "$NOEXT_CFNAME.$EXTENSIONTGT" ]]; then
      echo "WARNING: Skipping $CFNAME"
    else
      echo "Renaming $CFNAME"
      # Do the renaming ...
      mv "$CFNAME" "$NOEXT_CFNAME.$EXTENSIONTGT"
    fi
  done
  ;;
 *)
  # The -e for echo means that escape sequences like \n and \t get evaluated ...
  echo -e "ERROR: unknown command line switch\n\tSyntax: change <-r|--> <source-ext> <target-ext>"
  # Exit with non-zero (i.e. failure) status
  exit 1
esac

Синтаксис явно указан в сценарии. Я взял на себя свободу использовать соглашение --, отделяющее ключи командной строки от имен файлов. Таким образом, он выглядит чище и проще в реализации.

NB: можно сгущать это дальше. Но здесь я пытался донести очко, а не выиграть запутанный конкурс Bash;)

PS: также обрабатывает нечувствительный к регистру материал теперь в части переименования. Однако я решил пропустить, если целевой файл уже существует. Может быть переписан как опция командной строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...