为什么echo在引号内打印时会在80个字符中拆分长行? (以及如何修复它?)

时间:2014-09-05 11:37:15

标签: bash echo wc

没有引号的回声...... 1行。细

$ echo $(ls -1dmb /bin/*) > test
$ wc -l test
1 test

与引号相呼应... 396行。坏。

$ echo "$(ls -1dmb /bin/*)" > test
$ wc -l test
396 test

使用echo编写文件并扩展长变量时会出现问题。

为什么会这样?如何解决?

2 个答案:

答案 0 :(得分:2)

ls检测到您的stdout不是终端。

检查ls -1dmb /bin/* | cat vs ls -1dmb /bin/*的输出。它是ls,正在分割输出。

同样,对于ls --color=auto情况,使用color选项,基于stdout是否为终端。

当使用引号时,echo提供了一个参数,其中包含新行,空格,它们按原样回显到文件。

当未使用引号时,echo会提供多个参数,这些参数由IFS分隔。因此,echo将所有这些打印在一行中。 但是,don't skip these quotes ......

如何修复它:

我认为,分裂总是发生在一些文件名和...的末尾。从来没有在文件名之间。因此,这两个选项中的一个可能适合您:

ls -1dmb /bin/* | tr '\n' ' ' >test
ls -1dmb /bin/* | tr -d '\n' >test

答案 1 :(得分:0)

@anishsane正确回答了主题问题(ls正在进行包装以及删除它们的方法)并且也涵盖了引用问题,但引用问题负责行计数差异而不是{{1 }}

这里的问题完全是引用以及命令行,回显和命令替换如何工作。

ls的输出是一个单独的字符串,嵌入的换行符通过引号保护shell。将该值移至"$(ls ...)"echo将其吐出(使用换行符)。

echo的输出是一个不受shell保护的字符串,因此会进行单词拆分和空格规范化。命令替换不能提前终止你的命令行(你不希望在一个目录中有$(ls ...)来运行两个文件echo $(ls -1)你会吗?)新行被保留为{{1的参数之间的单词分隔符}}。然后shell将结果拆分为空格(包括换行符),并给echo一个参数列表,在该点echo first_file; second_file愉快地执行echo,正如您所猜测的那样,只输出一行输出。

试试看我的意思:

echo