处理 `mv` 的变量空间

Bum*_*Kim 2 bash mv

假设我有一个包含以下文件/目录的目录:

google
apple
mozilla foundation   # a file with spaces
browsers
Run Code Online (Sandbox Code Playgroud)

所以我想将文件移动到browsers目录中。这是我写的一个脚本:

for d in $(ls); do
    if ! [ "$d" == "browsers" ]; then
        mv "$d" "browsers"
    fi
done
Run Code Online (Sandbox Code Playgroud)

然后,googleapplebrowsers,但我得到:

mv: cannot stat 'mozilla': No such file or directory
mv: cannot stat 'foundation': No such file or directory
Run Code Online (Sandbox Code Playgroud)

显然,问题在于变量中的空格。处理这个问题的正确方法是什么?

当然,我相信应该有一个更优雅的单行命令来做到这一点,但我想知道我应该如何使用带有空格的变量。

Joh*_*024 6

千万不能永远使用:

for d in $(ls)
Run Code Online (Sandbox Code Playgroud)

改用这个:

for d in *
Run Code Online (Sandbox Code Playgroud)

除其他外,使用 的两个问题$(ls)是外壳将结果$(ls)归为分路径名扩展。在您的情况下,是分导致 mozilla foundation变成mozillafoundation

有关不使用的原因的详细讨论$(ls),请参阅“有什么作用$(ls *.txt)?”

如果您需要考虑目录中没有非隐藏文件的情况(这种情况for i in $(ls)可能看起来更好,因为它没有在循环中进行任何传递,而不是在循环中使用*as $iin进行一次传递for i in *(除了在zsh)) 中,您想告诉外壳不要为不匹配的 glob 扩展到任何内容:

  • zshfor i in *(N)
  • ksh93for i in ~(N)*
  • bash4.4+:(f() { local -; shopt -s nullglob; for i in *; ...; done; }; f重点是在nullglob本地使用该选项(另请参阅failglobzsh的默认行为类似的选项))。
  • yash:(set -o nullglob然后重置,yash据我所知,没有本地范围的选项)
  • 在其他 shell 中,您始终可以[ -e "$i" ] || [ -L "$i" ] || continue在循环中添加 a以检查文件是否存在。