动态重命名包含空格的文件

动态重命名包含空格的文件

我想根据包含空格的数据动态重命名文件

Name="Abc DEF"
Name1="GHI JKL"

mv /sample/pdf/noriginalName.pdf /sample/outputPdf/${NAME}${Name1}".pdf"

但它给了我一个错误,因为它之间遇到了空格。

我怎样才能做到这一点?

答案1

别担心,你不是第一个,也不会是最后一个被咬的人。这是有关 shell 的最常见问题,也是 shell 脚本中发现的大多数错误和安全漏洞的原因。这是由于早期 Unix 历史中 Bourne shell 和 Korn shell 的设计选择不当造成的。

在 Bourne shell 及其大多数后代(ksh、ash、pdksh、mksh、bash、dash、yash...)中,将变量不加引号是 split+glob 运算符。

最好的证明是:

$ var='*.txt,.*'
$ IFS=',' # default is space tab and newline
$ printf '<%s>\n' $var
<file.txt>
<.>
<..>

shell 已$var, 字符进行拆分,并在与相应模式匹配的文件列表中扩展了每个结果单词(在本例中包含通配符)。

这就是为什么,在类似 Bourne 的 shell 中(除了zsh),你必须总是引用你的变量(除非你确实想要分裂和/或全局

$ printf '<%s>\n' "$var"
<*.txt:.*>

所以在你的情况下:

mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"

或者:

mv /sample/pdf/noriginalName.pdf /sample/outputPdf/"${NAME}${Name1}".pdf

(只要变量被引用,引号放在哪里并不重要)。

您只能通过以下方式禁用拆分:

IFS=

您只能通过以下方式禁用通配符:

set -f # affects all globbing, not only the one done upon variable expansion.

和:

IFS=; set -f

您将获得与参数扩展相同的行为zsh,没有通配符,没有分割。但您仍然需要引用您的变量

cmd "$var"

如果你想cmd通过当为空或未设置时为空参数$var(与根本没有争论)。一个典型的例子是,[ -n "$var" ]如果您不引用$var,则测试将始终为真,因为何时$var为空,则解析为[ -n ]而不是[ -n '' ]

在 中zsh,通配符和拆分不会在变量扩展时隐式完成(除非在shksh仿真模式下)。您必须使用特定的扩展运算符显式请求它:$=var用于分词,$~var用于通配(或${~var};$~=var两者)。

其他不存在此类问题的 shell 是fish、 和rc及其后代 ( es, akanga)。

(t)csh

cmd "$var"

$var有帮助,但还不够,因为如果包含换行符,它不起作用。在那里,你需要:

cmd $var:q

答案2

您必须引用整个文件名:

mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"

使用双引号阻止bash和其他类似 Bourne 的 shell(除了zsh)执行场分裂变量扩展后。

相关内容