ciz*_*ixs 353 string bash shell echo
我想使用以下内容将一些预定义的文本写入文件:
text="this is line one\n
this is line two\n
this is line three"
echo -e $text > filename
Run Code Online (Sandbox Code Playgroud)
我期待这样的事情:
this is line one
this is line two
this is line three
Run Code Online (Sandbox Code Playgroud)
但得到了这个:
this is line one
this is line two
this is line three
Run Code Online (Sandbox Code Playgroud)
我很肯定每个人都没有空间\n
,但额外的空间是如何产生的?
new*_*kid 573
为此,Heredoc听起来更方便.它用于向命令解释程序发送多个命令,如ex或cat
cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
Run Code Online (Sandbox Code Playgroud)
'<<'后面的字符串表示停止的位置.
要将这些行发送到文件,请使用:
cat > $FILE <<- EOM
Line 1.
Line 2.
EOM
Run Code Online (Sandbox Code Playgroud)
您还可以将这些行存储到变量中:
read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM
Run Code Online (Sandbox Code Playgroud)
这会将行存储到名为的变量中<<
.
打印时,请记住变量周围的引号,否则您将看不到换行符.
echo "$VAR"
Run Code Online (Sandbox Code Playgroud)
更好的是,您可以使用缩进使其在代码中更突出.这次只需在"<<"之后添加一个" - "即可阻止标签显示.
read -r -d '' VAR <<- EOM
This is line 1.
This is line 2.
Line 3.
EOM
Run Code Online (Sandbox Code Playgroud)
但是,您必须在代码中使用制表符而不是空格来缩进.
And*_*ner 143
如果您正在尝试将字符串转换为变量,另一种简单的方法是这样的:
USAGE=$(cat <<-END
This is line one.
This is line two.
This is line three.
END
)
Run Code Online (Sandbox Code Playgroud)
如果使用制表符缩进字符串(即'\ t'),则缩进将被删除.如果缩进空格,缩进将保留.
注意:最后一个右括号在另一行上很重要.该END
文本必须出现在单独一行.
Jos*_*lly 73
echo
在传递给它的参数之间添加空格.$text
受变量扩展和单词拆分的影响,因此您的echo
命令相当于:
echo -e "this" "is" "line" "one\n" "this" "is" "line" "two\n" ...
Run Code Online (Sandbox Code Playgroud)
你可以看到在"this"之前会添加一个空格.您可以删除换行符,并引用$text
以保留换行符:
text="this is line one
this is line two
this is line three"
echo "$text" > filename
Run Code Online (Sandbox Code Playgroud)
或者您可以使用printf
,它比echo
以下更强大和便携:
printf "%s\n" "this is line one" "this is line two" "this is line three" > filename
Run Code Online (Sandbox Code Playgroud)
在bash
,支持大括号扩展,你甚至可以做:
printf "%s\n" "this is line "{one,two,three} > filename
Run Code Online (Sandbox Code Playgroud)
Chr*_*aes 37
在bash脚本中,以下工作:
#!/bin/sh
text="this is line one\nthis is line two\nthis is line three"
echo -e $text > filename
Run Code Online (Sandbox Code Playgroud)
或者:
text="this is line one
this is line two
this is line three"
echo "$text" > filename
Run Code Online (Sandbox Code Playgroud)
cat filename给出:
this is line one
this is line two
this is line three
Run Code Online (Sandbox Code Playgroud)
Mat*_*ski 34
我找到了更多解决方案,因为我想让每一行都正确缩进:
你可以使用echo
:
echo "this is line one" \
"\n""this is line two" \
"\n""this is line three" \
> filename
Run Code Online (Sandbox Code Playgroud)
如果你"\n"
刚刚\
放在一行的末尾,它就不起作用了.
或者,您可以使用printf
以获得更好的可移植性(我碰巧遇到了很多问题echo
):
printf '%s\n' \
"this is line one" \
"this is line two" \
"this is line three" \
> filename
Run Code Online (Sandbox Code Playgroud)另一个解决方案可能是:
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
Run Code Online (Sandbox Code Playgroud)
要么
text=''
text+="this is line one\n"
text+="this is line two\n"
text+="this is line three\n"
printf "%b" "$text" > filename
Run Code Online (Sandbox Code Playgroud)通过混合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
Run Code Online (Sandbox Code Playgroud)
在将缩进级别硬编码到代码中时,重构像这样格式化的代码并不容易.
可以使用辅助函数和一些变量替换技巧:
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"
Run Code Online (Sandbox Code Playgroud)Gab*_*les 10
对于我的一般口味来说,这看起来太像 bash 了:)(很难阅读):
cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
Run Code Online (Sandbox Code Playgroud)
让我们来一些更 Pythonic 的东西(这仍然是 bash):
text="this is line one
this is line two
this is line three\n"
dedent text
printf "$text" # print to screen
printf "$text" > file.txt # print to a file
Run Code Online (Sandbox Code Playgroud)
啊……这样好多了。:) 这让我想起了我在这里使用的Pythontextwrap.dedent()
函数。
下面是这个神奇dedent
函数的样子:
dedent() {
local -n reference="$1"
reference="$(echo "$reference" | sed 's/^[[:space:]]*//')"
}
Run Code Online (Sandbox Code Playgroud)
屏幕输出示例:
this is line one
this is line two
this is line three
Run Code Online (Sandbox Code Playgroud)
如果不调用dedent text
first`,输出将如下所示:
this is line one
this is line two
this is line three
Run Code Online (Sandbox Code Playgroud)
变量是通过引用text
传递的,这样函数内部的修改就会影响到函数外部的变量。dedent
有关更多详细信息、解释和参考,请参阅我的其他答案:Equivalent of python's textwrap dedent in bash
OP的引述(加上我的强调):
我确信每个后面都没有空格
\n
,但是多余的空格是如何出来的呢?
您最初的尝试是这样的:
text="this is line one\n
this is line two\n
this is line three"
echo -e $text
Run Code Online (Sandbox Code Playgroud)
...但是您的输出在第二行和第三行之前有一个额外的空格。为什么?
通过推论和实验,我的结论是echo
将行尾的实际换行符(实际按下时得到的换行符Enter)转换为空格。因此,该空格出现在文本中每个行之后的行之前。\n
\
因此,解决方案是通过在字符串引号内的任何行末尾添加反斜杠来转义每行末尾的真正换行符,如下所示:
text="this is line one\n\
this is line two\n\
this is line three"
echo -e "$text"
Run Code Online (Sandbox Code Playgroud)
不要在那些尾部反斜杠之前text="this is line one\n \
放置空格(如下所示:),否则该空格将直接返回到您的输出中,并导致您与额外的空格出现同样的问题!
或者,只需将我的技术与dedent
上面的函数一起使用,它还具有能够缩进代码的附加功能,使其看起来非常漂亮、美观和可读。
我听说正在寻找这个答案,但也想将其通过管道传递给另一个命令。给出的答案是正确的,但如果有人想通过管道传输它,您需要在多行字符串之前通过管道传输它,如下所示
echo | tee /tmp/pipetest << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
Run Code Online (Sandbox Code Playgroud)
这将允许您拥有多行字符串,但也可以将其放入后续命令的标准输入中。
以下是我为变量分配多行字符串的首选方法(我认为它看起来不错)。
read -r -d '' my_variable << \
_______________________________________________________________________________
String1
String2
String3
...
StringN
_______________________________________________________________________________
Run Code Online (Sandbox Code Playgroud)
在两种情况下,下划线的数量相同(此处为80)。
归档时间: |
|
查看次数: |
386968 次 |
最近记录: |