多文件重命名Bash脚本问题

时间:2013-06-14 03:37:45

标签: bash osx-lion osx-snow-leopard mv

我使用代码重命名文件,出现了一个非常有趣的问题:它在运行Mac OSX Lion 10.7.5的计算机上运行,​​但在Mac OSX 10.6.8 Snow Leopard上失败了。

代码是:

for i in *; do mv $i `echo $i | sed 's/..//'`; done

我得到的错误是:

usage: mv [-f | -i | -n] [-v] source target
   mv [-f | -i | -n] [-v] source ... directory

这很奇怪,因为如果不在for循环中,mv正常工作......

任何人都知道我该怎么做才能让它发挥作用?

2 个答案:

答案 0 :(得分:3)

您应该使用bash字符串替换:

for i in *; do mv $i ${i/??/}; done

for i in *; do mv $i ${i#??}; done

答案 1 :(得分:2)

如果您有包含空格的文件(或某些其他shell元控件),那么将所有变量引用放在双引号中至关重要。否则,如果您有例如i="File Name.txt",您将运行mv File Name.txt le Name.txt之类的命令,并且它会认为您指定的是4个文件名而不仅仅是2.另一个标准错误(您 >制作)正在使用for file in $(ls),在名称甚至变为变量之前,它会被空格混淆。

另外,我有点担心短文件名和名称冲突。即使你认为你没有任何短文件名,如果你有dotglob shell选项设置,你最终会尝试重命名伪文件“。”和“......”,这根本不会很好。另外,如果你有例如名为“abcdefg”和“cdefg”的文件,脚本将重命名第一个(静默删除第二个),然后将 重命名为“efg”。

所以,这是我提议的重写(也使用@ TrueY的缩短文件名的建议):

for i in *; do
    if [ ${#i} -le 2 ]; then
        echo "$i: not renamed (too short)" >&2
    elif [ -e "${i:2}" ]; then
        echo "$i: not renamed (${i:2} already exists)" >&2
    else
        mv "$i" "${i:2}"
    fi
done