Answers:
这个分配不删除换行字符,它实际上是在echo
做这个。您只需在字符串两边加上引号即可维护这些换行符:
echo "$testvar"
这将给您想要的结果。有关演示,请参见以下成绩单:
pax> cat num1.txt ; x=$(cat num1.txt)
line 1
line 2
pax> echo $x ; echo '===' ; echo "$x"
line 1 line 2
===
line 1
line 2
用空格替换换行符的原因并不完全与echo
命令有关,而是多种多样的组合。
给定命令行后,bash
根据IFS
变量的文档将其拆分为单词:
IFS:内部字段分隔符,用于扩展后的单词拆分...默认值为
<space><tab><newline>
。
这指定默认情况下,可以使用这三个字符中的任何一个将命令拆分为单个单词。之后,单词分隔符消失了,剩下的就是单词列表。
结合echo
文档(bash
内部命令),您将看到为什么输出空格:
echo [-neE] [arg ...]:输出args,以空格分隔,后跟换行符。
使用时echo "$x"
,它将根据强制将整个x
变量设为单个单词bash
,因此不会拆分。您可以看到:
pax> function count {
...> echo $#
...> }
pax> count 1 2 3
3
pax> count a b c d
4
pax> count $x
4
pax> count "$x"
1
在这里,该count
函数仅打印出给定参数的数量。在1 2 3
和a b c d
行动变体显示它。
然后,我们尝试使用x
变量的两个变体。在一个没有,有四个字报价显示,"test"
,"1"
,"test"
和"2"
。加引号使它成为一个单词"test 1\ntest 2"
。
这是由于包含换行符的IFS(内部字段分隔符)变量引起的。
$ cat xx1
1
2
$ A=`cat xx1`
$ echo $A
1 2
$ echo "|$IFS|"
|
|
一种解决方法是暂时将IFS重置为不包含换行符:
$ IFSBAK=$IFS
$ IFS=" "
$ A=`cat xx1` # Can use $() as well
$ echo $A
1
2
$ IFS=$IFSBAK
为了消除IFS的这一可怕变化:
IFS=$IFSBAK
echo "$(IFS=''; cat text.txt)"
Bash -ge 4具有内置的映射文件,可将标准输入中的行读取到数组变量中。
help mapfile
mapfile < file.txt lines
printf "%s" "${lines[@]}"
mapfile -t < file.txt lines # strip trailing newlines
printf "%s\n" "${lines[@]}"
也可以看看:
http://bash-hackers.org/wiki/doku.php/commands/builtin/mapfile
该envdir
实用程序提供了一种简便的方法。 envdir
使用文件表示环境变量,文件名映射到环境变量名称,文件内容映射到环境变量值。如果文件内容包含换行符,那么env var也会包含换行符。