我正在运行以下命令:
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
.