我有这段代码来重命名一堆文件:
#!/bin/bash
for file in $1
do
mv -i "${file}" "${file/pattern/replacement}"
done
如何用 $2 和 $3 替换“模式”和“替换”?
此代码不起作用:
#!/bin/bash
for file in $1
do
mv -i "${file}" "${file/$2/$3}"
done
我尝试使用以下 3 个参数重命名:(file_*.jpg jpg bak
结果应该是将所有*.jpg
文件重命名为*.bak
文件)。但它所做的只是:(mv -i file_01.jpg file_01.jpg
因此不会重命名任何内容,因为两个 mv 参数相同,而且它会在第一个文件处停止,即使有更多*.jpg
文件也是如此)。如果我手动在 bash 脚本中输入jpg
and而不是and那么它就可以工作。bak
$2
$3
答案1
你用以下方式调用你的脚本
./script file_*.jpg jpg bak
但*
在传递给脚本之前会被扩展。假设您有 files file_1.jpg
,file_2.jpg
并且file_3.jpg
在您的文件夹中,这就是调用的内容:
./script file_1.jpg file_2.jpg file_3.jpg jpg bak
这意味着${1} = file_1.jpg
,${2} = file_2.jpg
和${3} = file_3.jpg
.
如果您这样编写脚本(在您的示例中):${1} = jpg
和${2} = bak
,可能会更好。然后,您可以将这些变量存储在脚本中,调用shift 2
以删除它们,并只需使用以下命令即可循环所有位置参数
for file; do
# do something
done
答案2
这是我根据 @pfnuesel 和 @Stéphane Chazelas 的提示想出的代码:
#!/bin/bash
preview="false"
found="false"
if [ $# -eq 0 ]; then
echo "Syntax: ren [-p] expression replacement files..."
else
if [ "$1" == "-p" ] || [ "$1" == "-P" ]; then
preview="true"
shift
fi
expression=$1
replacement=$2
shift 2
for file; do
if [ -f "$file" ]; then
found="true"
if [ "$preview" == "true" ]; then
echo mv -i -- "${file}" "${file/$expression/$replacement}"
else
mv -i -- "${file}" "${file/$expression/$replacement}"
fi
fi
done
if [ "$found" != "true" ]; then
echo >&2 "Couldn't find files with the specified wildcard"
exit 1
fi
fi