多行字符串,带有多余的空格(保留缩进)

本文翻译自:Multi-line string with extra space (preserved indentation)

I want to write some pre-defined texts to a file with the following: 我想使用以下内容将一些预定义的文本写入文件:

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

echo -e $text > filename

I'm expecting something like this: 我期待这样的事情:

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

But got this: 但是得到这个:

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

I'm positive that there is no space after each \\n , but how does the extra space come out? 我很肯定每个\\n后都没有空格,但是多余的空格又如何出现呢?


#1楼

参考:https://stackoom.com/question/1cP5P/多行字符串-带有多余的空格-保留缩进


#2楼

in a bash script the following works: 在bash脚本中,以下工作:

#!/bin/sh

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

alternatively: 或者:

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

cat filename gives: cat文件名给出:

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

#3楼

echo adds spaces between the arguments passed to it. echo在传递给它的参数之间添加空格。 $text is subject to variable expansion and word splitting, so your echo command is equivalent to: $text会进行变量扩展和单词拆分,因此您的echo命令等效于:

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

You can see that a space will be added before "this". 您可以看到在“ this”之前将添加一个空格。 You can either remove the newline characters, and quote $text to preserve the newlines: 您可以删除换行符,并引用$text以保留换行符:

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

echo "$text" > filename

Or you could use printf , which is more robust and portable than echo : 或者,您可以使用printf ,它比echo更加健壮和可移植:

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

In bash , which supports brace expansion, you could even do: 在支持大括号扩展的bash ,您甚至可以执行以下操作:

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

#4楼

Heredoc sounds more convenient for this purpose. 为此,Heredoc听起来更方便。 It is used to send multiple commands to a command interpreter program like ex or cat 它用于将多个命令发送到命令解释程序,例如excat

cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

The string after << indicates where to stop. <<之后的字符串表示在何处停止。

To send these lines to a file, use: 要将这些行发送到文件,请使用:

cat > $FILE <<- EOM
Line 1.
Line 2.
EOM

You could also store these lines to a variable: 您还可以将这些行存储到变量中:

read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM

This stores the lines to the variable named VAR . 这会将行存储到名为VAR的变量中。

When printing, remember the quotes around the variable otherwise you won't see the newline characters. 打印时,请记住变量周围的引号,否则您将看不到换行符。

echo "$VAR"

Even better, you can use indentation to make it stand out more in your code. 更好的是,您可以使用缩进使其在代码中更加突出。 This time just add a - after << to stop the tabs from appearing. 这次只需在<<之后添加-即可阻止标签显示。

read -r -d '' VAR <<- EOM
    This is line 1.
    This is line 2.
    Line 3.
EOM

But then you must use tabs, not spaces, for indentation in your code. 但是,您必须在代码中使用制表符(而不是空格)来缩进。


#5楼

I've found more solutions since I wanted to have every line properly indented: 自从我希望正确缩进每一行以来,我发现了更多解决方案:

  1. You may use echo : 您可以使用echo

     echo "this is line one" \\ "\\n""this is line two" \\ "\\n""this is line three" \\ > filename 

    It does not work if you put "\\n" just before \\ on the end of a line. 如果将"\\n"放在行末\\之前,则不起作用。

  2. Alternatively, you can use printf for better portability (I happened to have a lot of problems with echo ): 另外,您可以使用printf以获得更好的可移植性(我碰巧对echo遇到很多问题):

     printf '%s\\n' \\ "this is line one" \\ "this is line two" \\ "this is line three" \\ > filename 
  3. Yet another solution might be: 另一个解决方案可能是:

     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 

    or 要么

     text='' text+="this is line one\\n" text+="this is line two\\n" text+="this is line three\\n" printf "%b" "$text" > filename 
  4. Another solution is achieved by mixing printf and sed . 通过混合printfsed可以实现另一种解决方案。

     if something then printf '%s' ' this is line one this is line two this is line three ' | sed '1d;$d;s/^ //g' fi 

    It is not easy to refactor code formatted like this as you hardcode the indentation level into the code. 当您将缩进级别硬编码到代码中时,重构这种格式的代码并不容易。

  5. It is possible to use a helper function and some variable substitution tricks: 可以使用辅助函数和一些变量替换技巧:

     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" 

#6楼

If you're trying to get the string into a variable, another easy way is something like this: 如果您尝试将字符串放入变量中,则另一种简单的方法是这样的:

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

If you indent your string with tabs (ie, '\\t'), the indentation will be stripped out. 如果使用制表符(即'\\ t')缩进字符串,则缩进将被删除。 If you indent with spaces, the indentation will be left in. 如果缩进空格,则缩进将保留。

NOTE: It is significant that the last closing parenthesis is on another line. 注:这显著的最后一个右括号是另一条线路上。 The END text must appear on a line by itself. END文本必须单独显示在一行上。

你可能感兴趣的:(多行字符串,带有多余的空格(保留缩进))