我一直在尝试编写一个 Mac Automator 服务来从文件名中删除非法字符。我已经成功了,但解决方案有点不优雅,我想知道是否有人有更好的解决方案。
我正在运行以下 Bash 脚本,该脚本将选定的文件作为参数传递给它。
for f in "$@"
do
cd $(dirname "$f")
mv "${f##*/}" $(echo "${f##*/}" | sed -e 's/[^A-Za-z0-9._-]/_/g')
done
它的作用是
cd /Desktop/test/
mv some file %^& test.txt some_file_____test.txt
cd
进入目录是让它工作的唯一方法mv
。它要么找不到文件,要么重命名整个文件路径,即
/Desktop/test/some file %^& test.txt to _Desktop_test_some_file_____test.txt
答案1
您可以使用 dirname/basename 将变量 $f 拆分为 $fdir 和 $fbase,并且仅编辑 $fbase,而不要使用目录,但它看起来并不比您的cd
解决方案好很多...(不要认为它需要参数扩展来删除 $fbase 中的斜杠部分,因此会稍微小一些。甚至可以使用模式替换来代替sed
,但sed
已经足够好了)
for f in "$@"
do
fbase=$(basename "$f")
fdir=$(dirname "$f")
mv "${fdir}${fbase}" "${fdir}$(echo "${fbase}" | sed -e 's/[^A-Za-z0-9._-]/_/g')"
done
但我还想知道您是否for f in "$@"
也可能陷入非法文件名的泥潭,没有经过 IFS 调整就无法正确地分离出 $f,但我敢打赌 Automator 会处理这些问题。
另一个选择可能是运行find
然后使用它-exec
或者-execdir
甚至xargs
查找和重命名文件,并且有一个rename
程序可以执行诸如“将大写名称转换为小写,你会使用”之类的操作,rename 'y/A-Z/a-z/' *
但这些可能无法很好地与 Automator 配合使用。
实际上,我将尝试一个快速测试,看看rename
单独使用具有完整路径的文件名会有什么效果......在回显正确的完整路径时会出现意外的“没有这样的文件”:
$ rename 'y/A-Z/a-z/' "/home/me/Downloads/NEWFILE-Z1.txt"
Can't rename /home/me/Downloads/NEWFILE-Z1.txt /home/me/downloads/newfile-z1.txt: No such file or directory
看起来与重命名相比并没有太大的改进,mv, but
可以减少子外壳、管道和回声......
$ rename -v 's/[^A-Za-z0-9._-]/_/g' New\ space\ file.txt
New space file.txt renamed as New_space_file.txt
我会将它放入脚本中,虽然更小但它又回到了cd
,并且"
引用也“围绕”子 shell 调用:
for f in "$@"
do
cd $(dirname "$f")
rename 's/[^A-Za-z0-9._-]/_/g' "$(basename "$f")"
done