有人可以解释一下这个有效的Bash代码吗?

时间:2017-06-02 17:28:38

标签: bash replace whitespace

Naidim回答了这个问题: How to replace spaces in file names using a bash script

这是我能为我工作的唯一答案,但我不明白我在看什么。

for f in *\ *; do mv "$f" "${f// /_}"; done
  1. 我不知道for循环会用这种基本语法搜索所有文件。
  2. 我看到了mv语句,但是命令扩展是什么?

3 个答案:

答案 0 :(得分:3)

打破它:

  • *\ *是文件名glob模式。这会扩展到当前目录中包含空格的所有文件。通常将单独的参数空间分隔(在glob扩展之前发生),但在它成为文字空间之前有\转义,因此是glob模式的一部分。

  • for f in *\ *;是一个for循环,循环遍历in之后的所有内容 - 在本例中是glob扩展的文件列表。变量f将依次设置为每个文件名,并且将为每个文件名执行最多done命令的代码。

  • "$f"是一个变量扩展。变量扩展来自字拆分之前的(与glob扩展不同),因此引号必须使文件名中的空格保持为单个参数的一部分,而不是拆分成多个参数。

    < / LI>
  • ${f// /_}是带替换的变量扩展。初始//表示将模式重复应用于变量内容,而不仅仅是一次。 / /之间的空格是要搜索的模式,最后的_是替换,因此f中的所有空格(循环中的文件名)将替换为下划线。

答案 1 :(得分:1)

您可能想要详细了解globbing和Bash parameter expansion以了解此代码。

  • *\ * =&gt;是一个glob,它匹配当前目录中的所有条目,其中还有一个空格
  • ${f// /_} =&gt; Bash参数展开,用变量-中的f替换空格(1:1替换)

因此,循环将获取当前目录(文件,目录,符号链接等)中名称中包含空格的所有条目,并将其重命名为使用_代替空格的名称。 / p>

答案 2 :(得分:0)

令人困惑的扩展是参数替换。表单${foo/bar/baz}用于在bar中搜索字符串$foo,并将其替换为baz。如果bar/开头(与您的循环中的情况一样),那么{em>所有次出现的bar都会被baz替换。有关详细信息,请阅读bash联机帮助页中的Parameter Expansion标题。