如何在不添加空格的情况下将 bash 中的字符串参数拆分为多行

如何在不添加空格的情况下将 bash 中的字符串参数拆分为多行

我正在运行以下命令:

some_command --flag "foo\
    bar\
    quux" arg2

这会导致字符串作为 传递foo\tbar\tquux

我正在寻找一种方法来传递此参数,而无需使用制表符(或添加其他空白字符)尽管保持缩进(以使我的脚本可读)。

答案1

some_command --flag "$(printf '%s' foo\
    bar\
    quux)" arg2

会这样做,尽管它不是最具可读性的。它将“foo”、“bar”和“quux”作为参数传递给printf命令,并%s作为格式字符串。当给出的格式字符少于参数时,格式字符串将根据需要重复,这相当于%s%s%s, 或依次打印所有三个字符串,且它们之间没有空格。最后,命令的输出printf“foobarquux”被替换为 的参数some_command

答案2

使用辅助函数:

concat () (
    IFS=
    printf '%s' "$*"
)

printf '"%s"\n' "$(concat "foo" \
    "bar" \
    "baz" )"

这将输出

"foobarbaz"

或者,首先将参数的字符串位放入数组中,然后单独创建实际参数(假设使用具有数组的 shell):

concat () (
    IFS=
    printf '%s' "$*"
)

args=(
    "foo"
    "bar"
    "baz"
)

concat_args=$( concat "${args[@]}" )

printf '"%s"\n' "$concat_args"

与上面的 POSIX shell 相同:

concat () (
    IFS=
    printf '%s' "$*"
)

set -- \
   "foo" \
   "bar" \
   "baz"

concat_args=$( concat "$@" )

printf '"%s"\n' "$concat_args"

请注意, exectues 的函数体concat在其自己的子 shell 中执行(这就是它(...)所做的),这意味着更改IFS是函数本地的。

在函数中使用"$*"代替的理由纯粹是为了美观。"$@"该计划"$*"将扩展至单身的将打印的字符串printf。在这种情况下,实际的连接是由$*不带分隔符(空)的 shell 扩展执行的$IFS。相反,使用它"$@"会扩展到多个单独的字符串,这些字符串printf将重复应用其格式字符串。在这种情况下,串联将是副作用将特定格式字符串与printf.

或者,同样的想法(单独创建实际参数字符串)但没有该辅助函数,

arg=\
"foo"\
"bar"\
"baz"

printf '"%s"\n' "$arg"

printf '"%s"\n'在所有情况下,上面都会被您的some_command --flag.

相关内容