我正在尝试重命名这样的文件:
for file in *;
do
mv -i "$file" "$(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')";
done
但是该sed
命令将所有空格替换为_
。
我如何编辑sed
命令以使其包含空格和指定字符?我试过使用,\s
但它不起作用...
编辑:
例如:文件trip: hill
,应该重命名为:trip_ hill
,但上述命令使其成为trip__hill
。
答案1
不要用sed
! 来解析文件名, 的输出echo "$file"
可能不可靠。
使用rename
。在 17.10 上你需要先安装它
sudo apt install rename
然后:
rename -n -- 's/[^-A-Za-z0-9_ .]/_/g' *
笔记
- 测试后删除
-n
以实际重命名文件 --
如果任何文件以以下方式开头,则为选项结束-
[^-A-Za-z0-9_ .]
我们不想替换的字符 - 放在-
第一个或最后一个,这样它就不能指示范围(它在这些位置上按字面意思处理)。- 类中可以包含空格
.
按照字面意思来理解(在其他正则表达式上下文中,它代表任何字符并且需要转义)。
这也适用于sed
:
$ echo 'trip: hill' | sed 's/[^-A-Za-z0-9 _.]/_/g'
trip_ hill
如果我在您的版本中在末尾添加一个空格,则会收到错误:
$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._- ]/_/g'
sed: -e expression #1, char 22: Invalid range end
但-
最后,它起作用了:
$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._ -]/_/g'
trip_ hill
因此,当您添加空格时,连字符的位置可能是导致问题的原因。但是不要解析文件名的建议仍然有效!
答案2
你也可以直接使用 shell,Bash 的参数扩展可以做替换:
for f in ./* ; do
mv "$f" "${f//[^-A-Za-z0-9._ ]/_}"
done
双斜杠告诉它替换所有匹配项,除此之外,语法很简单。