Bash延续线

时间:2011-09-06 07:06:26

标签: bash lines indentation continuation

你如何使用bash延续线?

我意识到你可以这样做:

echo "continuation \
lines"
>continuation lines

但是,如果你有缩进代码,它就不能很好地运行:

    echo "continuation \
    lines"
>continuation     lines

11 个答案:

答案 0 :(得分:138)

这是你可能想要的

$       echo "continuation"\
>       "lines"
continuation lines

如果这创建了两个echo参数而你只想要一个,那么让我们看看字符串连接。在bash中,将两个字符串放在彼此旁边连接:

$ echo "continuation""lines"
continuationlines

所以没有缩进的延续行是分解字符串的一种方法:

$ echo "continuation"\
> "lines"
continuationlines

但是当使用缩进时:

$       echo "continuation"\
>       "lines"
continuation lines

你得到两个参数,因为它不再是连接。

如果你想要一个跨越线条的单个字符串,虽然缩进但没有获得所有这些空格,你可以尝试的一种方法是抛弃延续线并使用变量:

$ a="continuation"
$ b="lines"
$ echo $a$b
continuationlines

这将允许您以额外的变量为代价来使用干净的缩进代码。如果你将变量设为局部变量,那就不会太糟糕了。

答案 1 :(得分:25)

此处带有<<-HERE终结符的文档适用于缩进的多行文本字符串。它将从此处的文档中删除任何前导选项卡。 (但是终止线仍将保留。)

cat <<-____HERE
    continuation
    lines
____HERE

另见http://ss64.com/bash/syntax-here.html

如果你需要保留一些(但不是全部)领先的空格,你可以使用像

这样的东西
sed 's/^  //' <<____HERE
    This has four leading spaces.
    Two of them will be removed by sed.
____HERE

对于在很多行上包装长复杂字符串,我喜欢printf

printf '%s' \
    "This will all be printed on a " \
    "single line (because the format string " \
    "doesn't specify any newline)"

答案 2 :(得分:7)

您可以使用bash arrays

$ str_array=("continuation"
             "lines")

然后

$ echo "${str_array[*]}"
continuation lines

还有一个额外的空间,因为(在bash手册之后):

  

如果单词是双引号,${name[*]}会扩展为单个单词   每个数组成员的值由第一个字符分隔   IFS变量

因此设置IFS=''以消除额外空间

$ IFS=''
$ echo "${str_array[*]}"
continuationlines

答案 3 :(得分:2)

我遇到了一种情况,我必须发送一条长消息作为命令参数的一部分,并且必须遵守行长度限制。命令看起来像这样:

somecommand --message="I am a long message" args

我解决这个问题的方法是将消息作为here文档移出(如@tripleee建议的那样)。但是这里的文档变成了标准输入,因此需要重新读入,我采用了以下方法:

message=$(
    tr "\n" " " <<- END
        This is a
        long message
END
)
somecommand --message="$message" args

这样做的好处是$message可以完全用作字符串常量,没有额外的空格或换行符。

请注意,上面的实际消息行每个都以tab字符作为前缀,这是由文档本身剥离的(因为使用了<<-)。最后仍有换行符,然后用dd替换为空格。

另请注意,如果您不删除换行符,则会在展开"$message"时显示原样。在某些情况下,您可以通过删除$message周围的双引号来解决此问题,但该消息将不再是单个参数。

答案 4 :(得分:2)

在某些情况下,使用Bash的串联功能可能是合适的。

示例:

temp='this string is very long '
temp+='so I will separate it onto multiple lines'
echo $temp
this string is very long so I will separate it onto multiple lines

从Bash手册页的“参数”部分:

  

name = [值] ...

     

...在上下文中,赋值语句正在将值分配给Shell变量或数组索引,可使用+ =运算符将其追加或添加到变量的先前值。如果将+ =应用于已设置了整数属性的变量,则值将作为算术表达式求值,并添加到该变量的当前值中,该值也会被求值。当使用复合赋值将+ =应用于数组变量时(请参见下面的数组),该变量的值不会未设置(如使用=时的情况一样),并且新值将从比数组最大索引大一个的位置追加到数组中(用于索引数组)或作为附加键值对添加到关联数组中。 应用于字符串值变量时,值将被扩展并附加到变量的值。

答案 5 :(得分:2)

行的延续也可以通过巧妙地使用语法来实现。

对于echo

# echo '-n' flag prevents trailing <CR> 
echo -n "This is my one-line statement" ;
echo -n " that I would like to make."
This is my one-line statement that I would like to make.

对于vars:

outp="This is my one-line statement" ; 
outp+=" that I would like to make." ; 
echo -n "${outp}"
This is my one-line statement that I would like to make.

关于vars的另一种方法:

outp="This is my one-line statement" ; 
outp="${outp} that I would like to make." ; 
echo -n "${outp}"
This is my one-line statement that I would like to make.

Voila!

答案 6 :(得分:1)

您可以根据需要在缩进中将其与换行符(不使用反斜杠)分开,如下所示,只需删除新行。

示例:

echo "continuation
of 
lines" | tr '\n' ' '

或者如果它是变量定义,则换行符会自动转换为空格。因此,仅在适用的情况下剥去额外的空间。

x="continuation
of multiple
lines"
y="red|blue|
green|yellow"

echo $x # This will do as the converted space actually is meaningful
echo $y | tr -d ' ' # Stripping of space may be preferable in this case

答案 7 :(得分:0)

  

但是,如果你有缩进代码,那么它的效果不会很好:

    echo "continuation \
    lines"
>continuation     lines

尝试使用单引号并连接字符串:

    echo 'continuation' \
    'lines'
>continuation lines

注意:连接包含空格。

答案 8 :(得分:0)

这并不是用户要求的,但是创建跨越多行的长字符串的另一种方法是通过逐步构建它,如下所示:

$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World

显然,在这种情况下,一次性构建起来会更简单,但是在处理较长的字符串时,这种样式非常轻巧且易于理解。

答案 9 :(得分:0)

根据您将承受的风险种类以及对数据的了解和信任程度,可以使用简单的变量插值法。

var liList = document.getElementById("reports-list").getElementsByTagName("li");
var listCount = liList.length;

if (listCount == 0) {
    $('#download-reports').css({'display': 'none !important'});
    $('#welcome-left').css({'width': '100% !important'});
} else if (listCount >= 1) {
    $('#download-reports').css({'display': 'block !important'});
    $('#welcome-left').css({'width': '65% !important'});
}

答案 10 :(得分:-2)

这可能并不能真正回答你的问题,但无论如何你可能会觉得它很有用。

第一个命令创建由第二个命令显示的脚本。

第三个命令使该脚本可执行。

第四个命令提供了一个用法示例。

john@malkovich:~/tmp/so$ echo $'#!/usr/bin/env python\nimport textwrap, sys\n\ndef bash_dedent(text):\n    """Dedent all but the first line in the passed `text`."""\n    try:\n        first, rest = text.split("\\n", 1)\n        return "\\n".join([first, textwrap.dedent(rest)])\n    except ValueError:\n        return text  # single-line string\n\nprint bash_dedent(sys.argv[1])'  > bash_dedent
john@malkovich:~/tmp/so$ cat bash_dedent 
#!/usr/bin/env python
import textwrap, sys

def bash_dedent(text):
    """Dedent all but the first line in the passed `text`."""
    try:
        first, rest = text.split("\n", 1)
        return "\n".join([first, textwrap.dedent(rest)])
    except ValueError:
        return text  # single-line string

print bash_dedent(sys.argv[1])
john@malkovich:~/tmp/so$ chmod a+x bash_dedent
john@malkovich:~/tmp/so$ echo "$(./bash_dedent "first line
>     second line
>     third line")"
first line
second line
third line

请注意,如果您确实想要使用此脚本,则将可执行脚本移动到~/bin更有意义,以便它可以在您的路径中。

检查python参考,了解textwrap.dedent如何工作的详细信息。

如果$'...'"$(...)"的使用令您感到困惑,请提出另一个问题(每个构建一个问题),如果还没有问题。提供您发现/询问的问题的链接可能会很好,以便其他人可以使用链接参考。