bash 使用换行符将文件内容转换为 unix 变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2789319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:16:00  来源:igfitidea点击:

File content into unix variable with newlines

bashunix

提问by Hugo

I have a text file test.txt with the following content:

我有一个包含以下内容的文本文件 test.txt:

text1
text2 

And I want to assign the content of the file to a UNIX variable, but when I do this:

我想将文件的内容分配给一个 UNIX 变量,但是当我这样做时:

testvar=$(cat test.txt)
echo $testvar

the result is:

结果是:

text1 text2

instead of

代替

text1
text2 

Can someone suggest me a solution for this?

有人可以建议我解决这个问题吗?

回答by paxdiablo

The assignment does notremove the newline characters, it's actually the echodoing this. You need simply put quotes around the string to maintain those newlines:

这个分配删除换行字符,它实际上是在echo做这个。您只需在字符串周围加上引号即可维护这些换行符:

echo "$testvar"

This wil give the result you want. See the following transcript for a demo:

这将给出你想要的结果。有关演示,请参阅以下成绩单:

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


The reasonwhy newlines are replaced with spaces is not entirelyto do with the echocommand, rather it's a combination of things.

用空格替换换行符的原因并不完全echo命令有关,而是多种因素的组合。

When given a command line, bashsplits it into words according to the documentation for the IFSvariable:

当给出命令行时,bash根据IFS变量的文档将其拆分为单词:

IFS:The Internal Field Separator that is used for word splitting after expansion ... the default value is <space><tab><newline>.

IFS:扩展后用于分词的内部字段分隔符……默认值为<space><tab><newline>

That specifies that, by default, any of those three characters can be used to split your command into individual words. After that, the word separators are gone, all you have left is a list of words.

这指定默认情况下,这三个字符中的任何一个都可用于将您的命令拆分为单个单词。之后,单词分隔符就消失了,剩下的就是单词列表。

Combine that with the echodocumentation (a bashinternal command), and you'll see why the spaces are output:

将其与echo文档(bash内部命令)结合起来,您将看到为什么输出空格:

echo [-neE] [arg ...]:Output the args, separated by spaces, followed by a newline.

echo [-neE] [arg ...]:输出args,以空格分隔,后跟换行符。

When you use echo "$x", it forces the entire xvariable to be a singleword according to bash, hence it's not split. You can see that with:

当您使用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

Here, the countfunction simply prints out the number of arguments given. The 1 2 3and a b c dvariants show it in action.

在这里,该count函数只是打印出给定参数的数量。在1 2 3a b c d行动变体显示它。

Then we try it with the two variations on the xvariable. The one withoutquotes shows that there are four words, "test", "1", "test"and "2". Adding the quotes makes it onesingle word "test 1\ntest 2".

然后我们尝试使用x变量的两个变体。在一个没有,有四个字报价显示,"test""1""test""2"。添加引号使其成为一个单词"test 1\ntest 2"

回答by DVK

This is due to IFS (Internal Field Separator)variable which contains newline.

这是由于包含换行符的IFS(内部字段分隔符)变量造成的。

$ cat xx1
1
2

$ A=`cat xx1`
$ echo $A
1 2

$ echo "|$IFS|"
|       
|

A workaround is to reset IFS to not contain the newline, temporarily:

一种解决方法是将 IFS 重置为暂时不包含换行符

$ IFSBAK=$IFS
$ IFS=" "
$ A=`cat xx1` # Can use $() as well
$ echo $A
1
2
$ IFS=$IFSBAK

To REVERT this horrible change for IFS:

为 IFS 恢复这个可怕的变化:

IFS=$IFSBAK

回答by todd

Bash -ge 4 has the mapfile builtin to read lines from the standard input into an array variable.

Bash -ge 4 内置了 mapfile 以将标准输入中的行读取到数组变量中。

help mapfile 

mapfile < file.txt lines
printf "%s" "${lines[@]}"

mapfile -t < file.txt lines    # strip trailing newlines
printf "%s\n" "${lines[@]}" 

See also:

也可以看看:

http://bash-hackers.org/wiki/doku.php/commands/builtin/mapfile

http://bash-hackers.org/wiki/doku.php/commands/builtin/mapfile

回答by DerWilts

Just if someone is interested in another option:

如果有人对另一种选择感兴趣:

content=( $(cat test.txt) )

a=0
while [ $a -le ${#content[@]} ]
do
        echo ${content[$a]}
        a=$[a+1]
done

回答by kenorb

Your variable is set correctly by testvar=$(cat test.txt). To display this variable which consist new line characters, simply add double quotes, e.g.

您的变量由testvar=$(cat test.txt). 要显示这个包含新行字符的变量,只需添加双引号,例如

echo "$testvar" 

Here is the full example:

这是完整的示例:

$ printf "test1\ntest2" > test.txt
$ testvar=$(<test.txt)
$ grep testvar <(set)
testvar=$'test1\ntest2'
$ echo "$testvar"
text1
text2
$ printf "%b" "$testvar"
text1
text2

回答by Chris Johnson

The envdirutility provides an easy way to do this. envdiruses files to represent environment variables, with file names mapping to env var names, and file contents mapping to env var values. If the file contents contain newlines, so will the env var.

envdir实用程序提供了一种简单的方法来执行此操作。 envdir使用文件来表示环境变量,文件名映射到 env var 名称,文件内容映射到 env var 值。如果文件内容包含换行符,那么 env var 也将包含换行符。

See https://pypi.python.org/pypi/envdir

https://pypi.python.org/pypi/envdir