Bash Can';我不能让这个代码工作
我正在编写一个bash shell脚本,它使用了一个带有三个选项的case:Bash Can';我不能让这个代码工作,bash,shell,Bash,Shell,我正在编写一个bash shell脚本,它使用了一个带有三个选项的case: 如果用户输入“change-r txt doc*”,则子目录中的文件扩展名将发生更改 如果用户输入“change-n-r doc”,则应重命名以-r或-n结尾的文件(这将把当前名为*.r的目录中的所有文件重命名为*.doc) 如果用户不输入任何内容,如“change txt doc*”,它只会更改当前目录中的文件扩展名 以下是我为其生成的代码(最后两个选项,我不确定如何实现): 有人能帮我修一下吗?或者至少告诉我哪里出
有人能帮我修一下吗?或者至少告诉我哪里出了问题?你应该重温一下字符串替换。实际上是各种各样的。Bash很擅长这些。Bash食谱的第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
#/bin/bash
#使其更灵活,以便以后改进命令行解析
开关=1美元
扩展名rc=$2
extensiongt=$3
#为唯一允许的开关匹配不同的情况(文件扩展名除外)
案例$SWITCH-in
-r |--)
#如果不是-r,我们将查找限制为当前目录
[[“x$SWITCH”==“x-r”]| | DONTRECURSE=“-maxdepth 1”
#当前文件夹中具有特定模式的文件(以及-r时的子文件夹)
找到$DONTRECURSE-iname“*.EXTENSIONSRC”|同时读取fname;做
#我们使用while来允许文件名中嵌入空格
#将项的规范名称获取到CFNAME中
CFNAME=$(readlink-f“$fname”)
#通过字符串替换实现条带扩展
NOEXT_CFNAME=“${CFNAME%.$EXTENSIONSRC}”
#如果目标存在,则跳过重命名。这可能是由于碰撞造成的
#使用不区分大小写的匹配。。。
如果[-f“$NOEXT\u CFNAME.$extensiongt”];然后
echo“警告:跳过$CFNAME”
其他的
echo“重命名$CFNAME”
#进行重命名。。。
mv“$CFNAME”$NOEXT\U CFNAME.$EXTENSIONGT”
fi
完成
;;
*)
#echo的-e表示像\n和\t这样的转义序列得到计算。。。
echo-e“错误:未知命令行开关\n\t语法:更改”
#以非零(即故障)状态退出
出口1
以撒
脚本中显然给出了语法。我可以自由地使用--
将命令行开关与文件名分离的约定。这样看起来更干净,实际上更容易实现
NB:可以进一步浓缩。但在这里,我试图表达自己的观点,而不是赢得混乱的Bash竞赛;)
PS:在重命名部分也处理不区分大小写的内容。但是,如果目标文件已经存在,我决定将其跳过。可能可以重写为命令行选项。代码有什么不起作用?@John,当我昨天运行它时(目前不在linux计算机附近),-r不会重命名文件扩展名。在“-n”(2)和“*”(3)选项中,我不知道如何编码。我需要帮助。@Deaths先生:你是说在各自的位置上有任何具有特定扩展名的文件吗?有一件事我真的不明白,
-n-r
..-n和-r是它需要的参数。因此,如果您输入“change-r txt doc*”(注意-r),它会这样做:“文件扩展名在子目录中被更改。”如果您输入“change-n-r doc”(注意-n),它会这样做:“重命名以-r或-n结尾的文件(这会将当前目录中名为*.r或*.n的所有文件重命名为*.doc)”@Mr teaths:正确的方法是遵循GNU标准解析命令行开关;)。。。使用--
将开关与文件名分开。正在开发一个小版本,至少可以让您开始。谢谢,但是您的代码太复杂了。你必须明白我仍然是bashshell脚本的新手。有没有更简单的方法可以实现这一点?这是我写的一段旧代码,与之类似。你能实现我想在里面做的吗/bin/sh#$1扩展名要重命名#$2为新扩展名EXTf=$1 EXTt=$2,而测试Z$3!=Z do NAME=$3 echo$NAME new=basename$NAME.$EXTf
echo$new mv$new.$EXTf$new.$EXTt shift请给我您的电子邮件地址,让我解释一下我想做得更好。@齿先生:对不起,不会在这样的开放位置提供它。代码有什么这么复杂?我应该多加评论吗?这不是问题,但我想你会知道基本的。@SAD,非常感谢你添加额外的评论,我可以理解你现在想做什么。最后一个版本是一个复杂的版本。这更清楚。不要担心电子邮件的事。这里有私人信息系统吗?@teots先生:不要认为有PM设施,尽管那会很酷。很高兴现在对你有用。如果你对剧本的某些部分有疑问,尽管问。
#!/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