我正在编写一个脚本来重命名我的文件,文件名的当前语法是program 1.c
,我想将其更改为cprogram-program1.c
.
我无法获得这种格式。简单化的几个条件是:
- 假设只有 10 个文件,即:0,1,2,3..9
我的程序来实现这一点:
首先我们需要过滤文件以找出遵循给定模式的文件
然后我们需要将文件名过滤到子字符串忽略器中以验证它们的格式是否正确
如果它们的格式正确,那么我们就可以按照我们需要的方式编辑文件名。
我陷入了步骤 1 和 2,这就是我正在做的事情:
for fn in *; do --> this loops over the files
program=${fn:0:7}
number=${..} --> number between 0 and 9
extension=${..} --> gets file extension like .c
if [ "$program" == "program" ]
then
if [ "$number" -ge 0 ] && [ "$number" -le 9 ]
then
if [ "$extension" == ".c" ]
then
--> edit code
fi
fi
fi
done
我的问题:我已经尝试了上述示例的许多排列,但我无法得到我想要的。任何帮助、简单的方法都将受到高度赞赏。
谢谢
答案1
for fn in *
do case $fn in
(program*[1-8].c)
: do something;;
(other*program*[09].ext)
: do something with this match;;
(this*match|*or*|*any*"$of"*these*matches)
: do something with these matches
: do as many lines as you want;;
(*) : catch all last default match
esac
done
语句中常用的技术case
是用比您通常所需的模式更具体的模式来修剪不需要的匹配。例如:
for fn in *
do case $fn in
(*[0-9][0-9].c) ;;
(program*[1-8].c)
echo mv "$fn" "${fn%???}0${fn#"${fn%???}"}"
esac
done
在上面的示例中,第一个*[0-9][0-9].c
模式匹配$fn
扩展名左侧可能出现两个或多个数字的所有值。这些匹配的执行块是空的 - null - 当找到匹配时什么也不会发生。但最重要的是,由于case
语句是自上而下工作的,这意味着与操作块匹配的唯一结果将仅包含扩展名左侧的一位数字,并且示例命令将在每个数字之前echo
插入一个0
发生在 1 到 8 之间的那些。
答案2
或者,放弃脚本并使用rename
工具代替。
令人沮丧的是,(至少)有两个不同的实例,具体rename
取决于您的发行版。在某些系统上,Perl 版本可能称为prename
.但是,您可以通过运行来判断您拥有哪一个rename -n ';' /dev/null
。如果没有任何反应,那么您拥有的是 Perl 版本。如果你收到一个错误,那就是另一个错误。
文件名的当前语法是
program 1.c
,我想将其更改为cprogram-program1.c
.假设只有 9 个文件即:0,1,2,3..9
基于 Perl 的
rename
(prename
)rename 's/^/cprogram-/; s/\s//' program\ ?.c
另一个
rename
rename -v 'program ' cprogram-program program\ ?.c