我有一个名为
的文件夹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
它试图将文件重命名为相同的名称。这是怎么回事?
答案 0 :(得分:3)
你忘了引用你的论点。
... mv "$f" "$(echo "$f" | ... )" ; done
答案 1 :(得分:3)
这是因为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/'` \;
注意:我是从内存中写的,我测试了这个,所以试试吧。
希望这有帮助。
答案 2 :(得分:3)
无需调用外部命令
#!/bin/bash
shopt -s nullglob
shopt -s extglob
for file in *.txt
do
newfile="${file//[)]/}"
newfile="${file// [(]/_}"
mv "$file" "${newfile%.txt}.in"
done
答案 3 :(得分:1)
正如您已修复的那样,您需要将$f
参数引用到mv
。
关于您的第二个问题,sed
不支持\d
。您可以改为使用[0-9]
。
答案 4 :(得分:0)
for f in *.txt ; do mv "$f" `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done
答案 5 :(得分:0)
如果你安装了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