【问题标题】:Why is bash echo adding new line in find results?为什么 bash echo 在查找结果中添加新行?
【发布时间】: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 with for"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 谢谢。我终于明白了。添加了我自己的答案,因为您似乎对此不感兴趣。

标签: bash find echo


【解决方案1】:

感谢 Gordon Davisson 和 his reference,我明白这并不像看起来那么简单:

while IFS= read -r -d $'\0' f; do
    printf "    %s\n" "$f"
done < <(find . -maxdepth 1 -type f -print0)

这使用 NULL 字节 (\0) 作为行分隔符,在每个文件名的末尾拆分 find 返回的数组(而不是每个空格,这是我得到错误的来源)。

【讨论】:

  • 想知道是否有更简单、更直观的方法来做同样的事情。
【解决方案2】:

我建议您使用printf 而不是echo,因为它提供的行为比echo 更一致。

#!/bin/bash
echo "Bash ${BASH_VERSION}"
for f in *.txt
do
printf "%s   " $f
done

上面的程序在同一行显示文件名,用制表符分隔,下面的程序用于换行。

#!/bin/bash
echo "Bash ${BASH_VERSION}"
for f in *.txt
do
printf "%s\n" $f
done

【讨论】:

  • 它不起作用。它将空格转换为制表符,所有文件都在同一行。如果我使用printf " %s\n" $f 将每个文件保留在单独的行中,则会返回原始问题(空格/制表符变为换行符)。
  • 我想知道为什么一个不起作用的答案会得到 2 个赞成票,而这个问题却没有……
  • @Rodrigo 真的很抱歉我没有很快回到这里,只是一些 covid 问题。实际上,添加printf "%s\n" $f 会给出正确的答案,就像我在这里给出之前​​在我的机器上尝试过的一样。
  • 它起作用了,因为你没有使用find。我的错误是在我引入find 时引起的,这是第一版和第二版之间的唯一区别。
  • 是的,因为find返回的数组和for循环遍历的数组不同。
猜你喜欢
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 2011-01-01
相关资源
最近更新 更多