我正在编写一个使用包含三个选项的案例的bash shell脚本:
这是我为它制作的代码(最后两个选项,我不知道如何实现):
#!/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
任何人都可以帮我解决这个问题吗?或者至少告诉我哪里出错了?
答案 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:现在还在重命名部分处理不区分大小写的内容。但是,如果目标文件已经存在,我决定跳过它。也许可以重写为命令行选项。