【发布时间】:2023-03-07 11:06:01
【问题描述】:
当我回显查找的结果时,bash 正在用换行符替换文件名的空格。第二个版本显示错误。这是为什么呢?
第一版:
#!/bin/bash
echo "Bash ${BASH_VERSION}"
for f in *.txt
do
echo " $f"
done
输出,没有错误:
Bash 5.0.3(1)-release
File 1.txt
File 2.txt
第二版:
#!/bin/bash
echo "Bash ${BASH_VERSION}"
for f in $(find . -maxdepth 1 -type f)
do
echo " $f"
done
有错误的输出:
Bash 5.0.3(1)-release
./File
1.txt
./File
2.txt
【问题讨论】:
-
这与
echo无关,这是由于$(find ...)被拆分为“单词”的方式——在任何类型的空格上。它还尝试扩展任何看起来像通配符的东西,这可能会导致真的奇怪的结果。见BashFAQ: "Why you don't read lines withfor" 和BashFAQ #20: "How can I find and safely handle file names containing newlines, spaces or both?" -
@GordonDavisson 我不明白。这里没有通配符。
$f被正确引用。它没有读取文件的 contents。我已经阅读了您的链接,但仍然不知道发生了什么。 -
由于
$(find ...)不在双引号中,因此其结果被拆分为“单词”——不是文件名,不是行,单词。那里有四个词:“./File”、“1.txt”、“./File”和“2.txt”。然后for使用这四个词作为要循环的东西,因此循环运行了四次;首先将f设置为“./File”,然后将其设置为“1.txt”,等等。另一方面,如果你双引号"$(find ...)",那么它就不会在全部,循环将运行一次,f设置为两个文件名,中间有一个换行符。请改用 BashFAQ #20 中的一种技术。 -
@GordonDavisson 谢谢。我终于明白了。添加了我自己的答案,因为您似乎对此不感兴趣。