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

Jim*_*nes 12 bash loops for-loop rename mv

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

for f in *.txt; do mv \"$f\" ${f/ /}; done
Run Code Online (Sandbox Code Playgroud)

但是,这会为每个文件提供错误"mv:target不是目录".如果我在命令中用'echo 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
Run Code Online (Sandbox Code Playgroud)

如果我输入命令:

for f in *.txt; do echo mv \"$f\" ${f/ /}; done
Run Code Online (Sandbox Code Playgroud)

我明白了:

mv "a .txt" a.txt
mv "b .txt" b.txt
Run Code Online (Sandbox Code Playgroud)

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

Joh*_*024 25

尝试:

for f in *.txt; do mv "$f" "${f// /}"; done
Run Code Online (Sandbox Code Playgroud)

三点:

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

  2. 通常,在shell变量的每个引用周围加上双引号是个好主意.

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

什么地方出了错

$ 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
Run Code Online (Sandbox Code Playgroud)

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

  • @CandidMoon如果您收到"非目录"消息,则可能意味着shell变量不是双引号.当然,不知道你正在做什么,我只能猜测. (2认同)

sdf*_*off 8

因为这是谷歌搜索这个错误时出现在谷歌上的第一件事,我想我会补充一点。

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

这有效(当 output.txt 不存在时):

mv file1.txt output.txt
Run Code Online (Sandbox Code Playgroud)

这不(如果 file2.txt 确实存在):

mv file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我正在做:mv prefix_* output_file_name确保下载的文件具有一致的名称,但另一个文件出现在目录中,导致“mv target is not a directory”错误