【发布时间】:2013-10-29 19:21:37
【问题描述】:
我正在尝试编写一个 bash 脚本来删除空格、下划线和点,并用破折号替换它们。我还设置为小写并删除括号。这是(长)第二个 sed 命令,它似乎有效。
第一个 sed 调用使用带有“\”的空格转义原始名称,就像我制表符完成时一样,这就是我认为的问题。
如果我用“echo”替换“mv -i”,我会得到我想要的:原始文件名用反斜杠转义,然后是新名称。如果我将它粘贴到终端中它可以工作,但是在脚本中使用 mv 时,空格会导致问题。转义不起作用。
#!/bin/bash
for a in "$@"; do
mv -i $(echo "$a" | sed -e 's/ /\\\ /g') $(echo "$a" | sed -e 's/\(.*\)/\L\1/' -e 's/_/-/g' -e 's/ /-/g' -e 's/---/--/g' -e 's/(//g' -e 's/)//g' -e 's/\[//g' -e 's/\]//g' -e 's/\./-/g' -e 's/-\([^-]*\)$/\.\1/')
done
另一种解决方案是在名称周围加上引号,但我不知道该怎么做。我觉得我已经接近了,但我被难住了。
我也考虑过“重命名”命令,但您不能像使用 sed 那样执行多个操作。
请指出任何其他问题,这是我的第一个脚本之一。我不确定我的“$@”或“$a”位是否完全正确。
干杯。
编辑:
示例输入文件名
I am a Badly [named] (file) - PLEASE.rename_me.JPG
应该变成
i-am-a-badly-named-file--please-rename-me.jpg
edit2:我的解决方案,根据 gniourf_gniourf 非常有用的纯 bash 答案进行了调整:
#!/bin/bash
for a in "$@"; do
b=${a,,} #lowercase
b=${b//[_[:space:]\.]/-} #subst dot,space,underscore with dash
b=${b//---/--} #remove triple dash
b=${b//[()\[\]]/} #remove brackets
if [ "${b%-*}" != "$b" ]; then #if there is a dash (prevents filename.filename)
b=${b%-*}.${b##*-} #replace final dash with a dot for extension
fi
if [ "$a" != "$b" ]; then #if there has been a change
echo '--->' "$b" #
#mv -i -- "$a" "$b" #rename
fi
done
仅当文件有空格等且没有扩展名时才会失败(例如,this BAD_filename 变为 this-bad.filename。但这些是媒体文件,应该有扩展名,所以无论如何我都必须对它们进行排序。
再次,欢迎更正和改进。我是这方面的新手
【问题讨论】:
-
现在你有两个问题。
-
我知道,需要详细说明吗?
-
没有。看看我的回答,你会看到如何以一种好的和理智的方式实现你的算法。
-
谢谢! (当我回复时,您的答案不存在)。我仍然不确定为什么我有两个问题。
-
mv -i -- "$a" $(echo "$a" | sed ....似乎可以在没有转义的情况下工作,也许我读了很多关于这个的内容,以至于我没有尝试明显的内容。