使用 shell 脚本批量重命名
Posted
技术标签:
【中文标题】使用 shell 脚本批量重命名【英文标题】:Batch renaming using shell script 【发布时间】:2011-04-02 05:08:27 【问题描述】:我有一个文件夹,其中的文件名为
input (1).txt
input (2).txt
input (3).txt
...
input (207).txt
如何将它们重命名为
input_1.in
input_2.in
input_3.in
...
input_207.in
我正在尝试这个
for f in *.txt ; do mv $f `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done
但它给了我
mv: target `(100).txt' is not a directory
mv: target `(101).txt' is not a directory
mv: target `(102).txt' is not a directory
...
我哪里做错了?
我现在已经加了引号,但我现在明白了
mv: `input (90).txt' and `input (90).txt' are the same file
它以某种方式试图将文件重命名为相同的名称。这是怎么回事?
【问题讨论】:
【参考方案1】:正如您已经修复的那样,您需要将 $f
参数引用到 mv
。
关于你的第二个问题,sed
不支持\d
。你可以改用[0-9]
。
【讨论】:
【参考方案2】:如果您安装了 GNU Parallel http://www.gnu.org/software/parallel/,您可以这样做:
seq 1 207 | parallel -q mv 'input ().txt' input_.in
观看 GNU Parallel 的介绍视频以了解更多信息: http://www.youtube.com/watch?v=OpaiGYxkSuQ
【讨论】:
【参考方案3】:for f in *.txt ; do mv "$f" `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done
【讨论】:
【参考方案4】:无需调用外部命令
#!/bin/bash
shopt -s nullglob
shopt -s extglob
for file in *.txt
do
newfile="$file//[)]/"
newfile="$file// [(]/_"
mv "$file" "$newfile%.txt.in"
done
【讨论】:
【参考方案5】:那是因为 bash for
用空格' ' 分割元素,所以你命令它将'input
' 移动到'(1)
'。
解决这个问题的方法是告诉 bash 使用 IFS
变量换行。
像这样:
IFS=$'\n'
然后执行你的命令。
不过,我建议您使用find
来代替-exec
命令。
例如:
find *.txt -exec mv "" `echo "" | sed -e 's/input\ (\([0-9]*\))\.txt/input_\1.in/'` \;
注意:我是凭记忆写的,我确实对此进行了测试,所以让我们尝试调整一下。
希望这会有所帮助。
【讨论】:
还是这个mv: 'input (90).txt' and 'input (90).txt' are the same file
我不认为你可以使用 '\d'(我记得),尝试使用 '[0-9]'。
@Lazer: 在sed
转义\d
引入了十进制字符表示\d97
== "a"【参考方案6】:
你忘记引用你的论点了。
... mv "$f" "$(echo "$f" | ... )" ; done
【讨论】:
以上是关于使用 shell 脚本批量重命名的主要内容,如果未能解决你的问题,请参考以下文章