无法使此代码生效

时间:2011-04-01 19:09:47

标签: bash shell

我正在编写一个使用包含三个选项的案例的bash shell脚本:

  1. 如果用户输入“change -r txt doc *”,则会在子目录中更改文件扩展名。
  2. 如果用户输入“change -n -r doc”,它应该重命名以。-r或。-n结尾的文件(这将重命名当前目录中名为* .- r的所有文件为* .doc)
  3. 如果用户没有输入任何内容,如“更改txt doc *”,则只更改当前目录中的文件扩展名。
  4. 这是我为它制作的代码(最后两个选项,我不知道如何实现):

    #!/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 个答案:

答案 0 :(得分:2)

你应该注意的是字符串替换。实际上他们各种各样。 Bash非常适合那些人。 Bash Cookbook的第105页(食谱5.18)非常适合阅读。

#!/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:现在还在重命名部分处理不区分大小写的内容。但是,如果目标文件已经存在,我决定跳过它。也许可以重写为命令行选项。