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
File content into unix variable with newlines
提问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 echo
doing 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 echo
command, rather it's a combination of things.
用空格替换换行符的原因并不完全与echo
命令有关,而是多种因素的组合。
When given a command line, bash
splits it into words according to the documentation for the IFS
variable:
当给出命令行时,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 echo
documentation (a bash
internal 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 x
variable 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 count
function simply prints out the number of arguments given. The 1 2 3
and a b c d
variants show it in action.
在这里,该count
函数只是打印出给定参数的数量。在1 2 3
和a b c d
行动变体显示它。
Then we try it with the two variations on the x
variable. 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 envdir
utility provides an easy way to do this. envdir
uses 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 也将包含换行符。