我想写一些预定义的文本与以下文件:

text="this is line one\n
this is line two\n
this is line three"

echo -e $text > filename

我期待的是这样的:

this is line one
this is line two
this is line three

但我明白了:

this is line one
 this is line two
 this is line three

我确信在每个\n之后没有空间,但额外的空间是如何出来的?


当前回答

我听到这个答案,但也想把它输送到另一个命令。给出的答案是正确的,但如果有人想要管道它,您需要在像这样的多行字符串之前管道它

echo | tee /tmp/pipetest << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

这将允许您拥有多行字符串,但也可以将其放在后续命令的stdin中。

其他回答

Echo在传递给它的参数之间添加空格。$text受变量扩展和单词分割的影响,所以你的echo命令相当于:

echo -e "this" "is" "line" "one\n" "this" "is" "line" "two\n"  ...

你可以看到在“this”之前加了一个空格。你可以删除换行符,并引用$text来保留换行符:

text="this is line one
this is line two
this is line three"

echo "$text" > filename

或者你可以使用printf,它比echo更健壮和可移植:

printf "%s\n" "this is line one" "this is line two" "this is line three" > filename

在支持大括号展开的bash中,你甚至可以这样做:

printf "%s\n" "this is line "{one,two,three} > filename

在bash脚本中,以下工作:

#!/bin/sh

text="this is line one\nthis is line two\nthis is line three"
echo -e $text > filename

另外:

text="this is line one
this is line two
this is line three"
echo "$text" > filename

Cat文件名给出:

this is line one
this is line two
this is line three

或者用空格保持文本缩进:

#!/bin/sh

sed 's/^[[:blank:]]*//' >filename <<EOF
    this is line one
    this is line two
    this is line three
EOF

相同但使用变量:

#!/bin/sh

text="$(sed 's/^[[:blank:]]*//' << whatever
    this is line one
    this is line two
    this is line three
)"

echo "$text" > filename

;-)

有很多方法可以做到这一点。对我来说,将缩进的字符串输送到sed中效果很好。

printf_strip_indent() {
   printf "%s" "$1" | sed "s/^\s*//g" 
}

printf_strip_indent "this is line one
this is line two
this is line three" > "file.txt"

这个答案是基于Mateusz Piotrowski的回答,但做了一些改进。

如果你试图将字符串转换为变量,另一种简单的方法是这样的:

USAGE=$(cat <<-END
    This is line one.
    This is line two.
    This is line three.
END

)

如果你用制表符缩进字符串(例如,'\t'),缩进将被删除。如果使用空格缩进,则缩进将保留。

注意:最后一个右括号在另一行,这很重要。END文本必须单独出现在一行中。