首页 文章

带有额外空间的多行字符串(保留缩进)

提问于
浏览
259

我想使用以下内容将一些预定义的文本写入文件:

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 之后都没有空间,但额外空间是如何产生的呢?

7 回答

  • 1

    为此,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
    

    但是,您必须在代码中使用制表符而不是空格来缩进 .

  • 96

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

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

    如果使用制表符缩进字符串(即“\ t”),则缩进将被删除 . 如果缩进空格,缩进将保留 .

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

  • 58

    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
    
  • 29

    在bash脚本中,以下工作:

    #!/bin/sh
    
    text="this is line one\nthis is line two\nthis is line three"
    echo $text > filename
    

    alternatively:

    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
    
  • 430

    我找到了更多解决方案,因为我想让每一行都正确缩进:

    • 您可以使用 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
    
    • 可以混合 printfsed . 但是,当您将缩进级别硬编码到代码中时,重构这样的代码并不容易 . 我将示例放在if块中,以便有一些缩进:
    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"
    
  • 0

    如果你把它放在下面它会工作:

    AA='first line
    \nsecond line 
    \nthird line'
    echo $AA
    output:
    first line
    second line
    third line
    
  • 23

    以下是我将多行字符串分配给变量的首选方法(我觉得它看起来不错) .

    read -r -d '' my_variable << \
    _______________________________________________________________________________
    
    String1
    String2
    String3
    ...
    StringN
    _______________________________________________________________________________
    

    在两种情况下,下划线的数量是相同的(这里是80) .

相关问题