我想使用以下内容将一些预定义的文本写入文件:
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
之后没有空间,但额外空间是如何产生的?
为此,Heredoc听起来更方便。它用于向命令解释程序发送多个命令,如ex或cat
cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
<<
之后的字符串表示停止的位置。
要将这些行发送到文件,请使用:
cat > $FILE <<- EOM
Line 1.
Line 2.
EOM
您还可以将这些行存储到变量中:
read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM
这会将行存储到名为VAR
的变量中。
打印时,请记住变量周围的引号,否则您将看不到换行符。
echo "$VAR"
更好的是,您可以使用缩进使其在代码中更突出。这次只是在-
之后添加一个<<
来阻止标签出现。
read -r -d '' VAR <<- EOM
This is line 1.
This is line 2.
Line 3.
EOM
但是,您必须在代码中使用制表符而不是空格来缩进。
如果您正在尝试将字符串转换为变量,另一种简单的方法是这样的:
USAGE=$(cat <<-END
This is line one.
This is line two.
This is line three.
END
)
如果使用制表符缩进字符串(即“\ t”),则缩进将被删除。如果缩进空格,缩进将保留。
注意:最后一个右括号在另一行上很重要。 END
文本必须单独出现在一行上。
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 $text > filename
或者:
text="this is line one
this is line two
this is line three"
echo "$text" > filename
cat filename给出:
this is line one
this is line two
this is line three
我找到了更多解决方案,因为我想让每一行都正确缩进:
echo
:
echo "this is line one" \
"\n""this is line two" \
"\n""this is line three" \
> filename
如果你把"\n"
放在\
之前的行尾就不行了。printf
以获得更好的可移植性(我碰巧在echo
上遇到了很多问题):
printf '%s\n' \
"this is line one" \
"this is line two" \
"this is line three" \
> filename
text=''
text="${text}this is line one\n"
text="${text}this is line two\n"
text="${text}this is line three\n"
printf "%b" "$text" > filename
要么
text=''
text+="this is line one\n"
text+="this is line two\n"
text+="this is line three\n"
printf "%b" "$text" > filename
printf
和sed
实现另一种解决方案。
if something
then
printf '%s' '
this is line one
this is line two
this is line three
' | sed '1d;$d;s/^ //g'
fi
在将缩进级别硬编码到代码中时,重构像这样格式化的代码并不容易。unset text
_() { text="${text}${text+
}${*}"; }
# That's an empty line which demonstrates the reasoning behind
# the usage of "+" instead of ":+" in the variable substitution
# above.
_ ""
_ "this is line one"
_ "this is line two"
_ "this is line three"
unset -f _
printf '%s' "$text"
以下是我为变量分配多行字符串的首选方法(我觉得它看起来不错)。
read -r -d '' my_variable << \
_______________________________________________________________________________
String1
String2
String3
...
StringN
_______________________________________________________________________________
在两种情况下,下划线的数量是相同的(这里是80)。
如果你把它放在下面它会工作:
AA='first line
\nsecond line
\nthird line'
echo $AA
output:
first line
second line
third line