我正在尝试编写一个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
,这只会失败。但这些是媒体文件,应该有扩展名,所以无论如何我都要对它们进行排序。 / p>
同样,欢迎更正和改进。我是这个东西的新手
答案 0 :(得分:4)
尝试使用rename
执行此操作:
rename 's/[_\s\.]/-/g' *files
来自shell
提示符的。它非常有用,如果需要,您可以在其中放入一些perl代码。
当您的测试成为值时,您可以删除-n
(干运行模式开关)。
warning http://pix.toile-libre.org/upload/original/1377510865.png 还有其他同名工具可能会或可能不会这样做,所以要小心。
如果您运行以下命令(linux
)
$ file $(readlink -f $(type -p rename))
你有一个像
的结果.../rename: Perl script, ASCII text executable
然后这似乎是正确的工具=)
如果没有,请将其设为Debian
上的默认值(通常已经是这种情况)和Ubuntu
之类的衍生物:
$ sudo update-alternatives --set rename /path/to/rename
(将/path/to/rename
替换为perl's rename
命令的路径。
最后但并非最不重要的是,这个工具最初是由Perl的父亲Larry Wall编写的。
答案 1 :(得分:0)
只是为了记录,请看:
$ a='I am a Badly [named] (file) - PLEASE.rename_me.JPG'
$ # lowercase that
$ echo "${a,,}"
i am a badly [named] (file) - please.rename_me.jpg
$ # Cool! let's save that somewhere
$ b=${a,,}
$ # substitution 's/[_ ]/-/g:
$ echo "${b//[_ ]/-}"
i-am-a-badly-[named]-(file)---please.rename-me.jpg
$ # or better, yet:
$ echo "${b//[_[:space:]]/-}"
i-am-a-badly-[named]-(file)---please.rename-me.jpg
$ # Cool! let's save that somewhere
$ c=${b//[_[:space:]]/-}
$ # substitution 's/---/--/g' (??)
$ echo "${c//---/--}"
i-am-a-badly-[named]-(file)--please.rename-me.jpg
$ d=${c//---/--}
$ # substitution 's/()[]//g':
$ echo "${d//[()\[\]]/}"
i-am-a-badly-named-file--please.rename-me.jpg
$ e="${d//[()\[\]]/}"
$ # substitution 's/\./-/g':
$ echo "${e//\./-}"
i-am-a-badly-named-file--please-rename-me-jpg
$ f=${e//\./-}
$ # substitution 's/-\([^-]*\)$/\.\1/':
$ echo "${f%-*}.${f##*-}"
i-am-a-badly-named-file--please-rename-me.jpg
$ # Done!
现在,这是你想要实现的100%bash实现:
#!/bin/bash
for a in "$@"; do
b=${a,,}
b=${b//[_[:space:]]/-}
b=${b//---/--}
b=${b//[()\[\]]/}
b=${b//\./-}
b=${b%-*}.${b##*-}
mv -i -- "$a" "$b"
done
是的,完成了!
所有这一标准,称为shell parameter expansion。
备注。对于更强大的脚本,您可以检查a是否有扩展名(读取:名称中的句点),否则算法的最后一次替换会失败。为此,请将以下行放在for
语句下面:
[[ a != *.* ]] && { echo "Oh no, file \`$a' has no extension..."; continue; }
(这条线的*.*
部分不是很可爱吗?)