如何在不使用多个回显调用的情况下在 Bash 中输出多行字符串,如下所示:
echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo
echo "Report bugs to: "
echo "up home page: "
我正在寻找一种可移植的方式来做到这一点,只使用 Bash 内置。
如何在不使用多个回显调用的情况下在 Bash 中输出多行字符串,如下所示:
echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo
echo "Report bugs to: "
echo "up home page: "
我正在寻找一种可移植的方式来做到这一点,只使用 Bash 内置。
此处的文档通常用于此目的。
cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to:
up home page:
EOF
所有 Bourne 衍生的 shell 都支持它们,包括所有版本的 Bash。
或者你可以这样做:
echo "usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to:
up home page: "
受此页面上富有洞察力的答案的启发,我创建了一种混合方法,我认为这是最简单和更灵活的方法。你怎么看?
首先,我在一个变量中定义了用法,这允许我在不同的上下文中重用它。格式非常简单,几乎所见即所得,无需添加任何控制字符。这对我来说似乎相当便携(我在 MacOS 和 Ubuntu 上运行它)
__usage="
Usage: $(basename $0) [OPTIONS]
Options:
-l, --level <n> Something something something level
-n, --nnnnn <levels> Something something something n
-h, --help Something something something help
-v, --version Something something something version
"
然后我可以简单地将它用作
echo "$__usage"
甚至更好的是,在解析参数时,我可以在其中以单行方式回显它:
levelN=${2:?"--level: n is required!""${__usage}"}
由于我printf
在评论中推荐过,我可能应该给出一些它的用法示例(尽管为了打印使用信息,我更有可能使用 Dennis 或 Chris 的答案)。 printf
使用起来比echo
. 它的第一个参数是一个格式字符串,其中总是解释转义符(如\n
) ;它还可以包含以 开头的格式指令,这些指令控制在其中包含任何附加参数的位置和方式。以下是将其用于使用消息的两种不同方法:%
首先,您可以在格式字符串中包含整个消息:
printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: \nup home page: \n"
请注意,与 不同的是echo
,您必须明确包含最后的换行符。此外,如果消息恰好包含任何%
字符,则必须将它们写为%%
. 如果您想包含错误报告和主页地址,可以很自然地添加它们:
printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: %s\nup home page: %s\n" "$bugreport" "$homepage"
其次,您可以使用格式字符串使其在单独的行上打印每个附加参数:
printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: " "up home page: "
使用此选项,添加错误报告和主页地址非常明显:
printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: $bugreport" "up home page: $homepage"
此外,对于缩进的源代码,您可以使用<<-
(带有尾随破折号)忽略前导制表符(但不是前导空格)。
例如这个:
if [ some test ]; then
cat <<- xx
line1
line2
xx
fi
输出没有前导空格的缩进文本:
line1
line2
我通常使用我认为更灵活和直观的内置读取命令。它将一行的内容读入一个变量,并允许与特殊的 shell 变量 IFS 绑定的分词。有关更多详细信息,请参阅此博客甚至手册页。
read -r -d '' usage <<-EOF
usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to: $report server
up home page: $HOME
EOF
echo "$usage"
使用 -e 参数和转义字符 \n:
echo -e "This will generate a next line \nThis new line is the result"
还有一件事,使用printf
预定义变量(此处:)msg
作为模板。
msg="First line %s
Second line %s
Third line %s
"
one='additional message for the first line'
two='2'
tri='this is the last one'
printf "$msg" "$one" "$two" "$tri"
此 ^^^ 将打印整个消息,其中插入了其他变量,而不是%s
按提供的顺序。
You can write your
text
freely,
in a separate:
----file.
接着
echo "$(</pathto/your_multiline_file)"
做这个:
dedent() {
local -n reference="$1"
reference="$(echo "$reference" | sed 's/^[[:space:]]*//')"
}
text="this is line one
this is line two
this is line three\n"
# `text` is passed by reference and gets dedented
dedent text
printf "$text"
输出不先调用dedent
:
this is line one
this is line two
this is line three
...并首先调用 WITH dedent
(如上所示):
this is line one
this is line two
this is line three
有关完整的解释,请参阅我已经写过的地方:
当然,感谢@Andreas Louv 在这里向我展示了sed
该功能的一部分。