bash错误重命名带空格的文件 - mv target不是目录

时间:2014-10-23 00:19:15

标签: bash loops for-loop rename mv

我试图重命名一堆包含空格的文件,摆脱空格。我以为我找到了正确的bash命令:

for f in *.txt; do mv \"$f\" ${f/ /}; done

但是,这会给出错误," mv:target不是目录"对于每个文件。如果我更换' mv'与回声mv'在命令中,它为每个文件打印正确的mv命令,如果我单独键入任何这些mv命令,它们就可以工作。例如,如果我有2个文件," a .txt"和" b .txt",并运行上面的命令,我得到:

mv: target 'a.txt' is not a directory
mv: target 'b.txt' is not a directory

如果我输入命令:

for f in *.txt; do echo mv \"$f\" ${f/ /}; done

我明白了:

mv "a .txt" a.txt
mv "b .txt" b.txt

我找到了另一种方法,使用"重命名",但我想知道为什么这不起作用。

2 个答案:

答案 0 :(得分:23)

尝试:

for f in *.txt; do mv "$f" "${f// /}"; done

三点:

  1. 不应转义shell变量周围的引号。

  2. 一般来说,最好在shell变量的每个引用周围加上双引号。

  3. ${f/ /}仅删除第一次出现的空格。要删除所有空格,请使用${f// /}

  4. 出了什么问题

    $ touch {a,b}" .txt"
    $ ls *.txt
    a .txt  b .txt
    $ for f in *.txt; do mv \"$f\" ${f/ /}; done
    mv: target `a.txt' is not a directory
    mv: target `b.txt' is not a directory
    

    表达式\"$f\"的行为与双引号不同。它扩展为两个参数,例如"a.txt",其中双引号被视为普通字符,就像a是普通字符一样。因为mv"a.txt"以及a.txt)有三个参数,mv认为您试图将前两个参数移到第三个参数第三个必须是一个目录。由于第三个不是目录,因此会发出错误消息。

答案 1 :(得分:1)

因为这是谷歌搜索此错误时首先出现在Google上的东西,所以我想补充一点。

如果您有两个以上的参数并且最后的结果不是目录,则会发生此错误。

这有效:

mv file1.txt output.txt

这不是:

mv file1.txt file2.txt

在我的情况下,我正在执行mv prefix_* output_file_name,以确保下载的文件具有一致的名称,但是目录中出现了另一个文件,导致出现“ MV目标不是目录”错误