3

我在使用代码重命名文件时出现了一个非常有趣的问题:它在运行 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

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

任何人都知道我应该怎么做才能让它工作?

4

2 回答 2

3

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

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

或者

for i in *; do mv $i ${i#??}; done
于 2013-06-14T04:18:09.017 回答
2

如果您有带空格的文件(或某些其他 shell 元字符),那么将所有变量引用放在双引号中至关重要。否则,如果你有 eg i="File Name.txt",你将运行一个类似的命令mv File Name.txt le Name.txt,它会认为你指定了 4 个文件名而不仅仅是 2 个。另一个标准错误(你没有犯)是 using 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
于 2013-06-14T14:55:45.400 回答