如何将“$@”或数组连接到一个字符串

如何将“$@”或数组连接到一个字符串

我正在尝试实现这个 helper bash 函数:

ores_simple_push(){(

  set -eo pipefail
  git add .
  git add -A

  args=("$@")

  if [[ ${#args[@]} -lt 1 ]]; then
      args+=('squash-this-commit')
  fi

  git commit -am "'${args[@]}'" || { echo; }
  git push

)}

with: git commit -am 'some stuff here',我真的不喜欢输入引号,所以我希望这样做:

ores_simple_push my git commit message here gets put into a single string

这样就变成:

git commit -am 'my git commit message here gets put into a single string'

有没有一个明智的方法来做到这一点?

答案1

在类似 Korn/POSIX 的 shell 中,当"$@"扩展为所有位置参数时,分开(在列表上下文中),如果未设置或则"$*"扩展为位置参数与第一个字符(某些 shell 中的字节)$IFS或 SPC 的串联$IFS没有任何 if$IFS设置为空字符串。

ksh// zsh/ (具有数组支持的类似 Bournebash的shell)中, vsyash也是如此。"${array[@]}""${array[*]}"

zsh,中与 /"$array"相同,"${array[*]}"而在ksh/中bash与 相同"${array[0]}"。中yash,与 相同"${array[@]}"

在 中,您可以使用参数扩展标志zsh将具有任意分隔符的数组元素连接起来:例如在空间上连接。它不限于单个字符/字节字符串,您还可以使用参数扩展标志来在分隔符规范中使用转义序列或变量(例如在 TAB 上连接以及与 的内容连接)。另请参阅使用换行符连接的快捷方式标志(与 相同)。j"${(j[ ])array}""${(j[ and ])array}"p"${(pj[\t])array}""${(pj[$var])array}"$varFpj[\n]

所以在这里:

ores_simple_push() (
  set -o errexit -o pipefail
  git add .
  git add -A

  args=("$@")

  if [[ ${#args[@]} -lt 1 ]]; then
      args+=('squash-this-commit')
  fi

  IFS=' '
  git commit -am "${args[*]}" || true
  git push
)

或者只是 POSIXly:

ores_simple_push() (
  set -o errexit
  git add .
  git add -A

  [ "$#" -gt 0 ] || set square-this-commit

  IFS=' '
  git commit -am "$*" || true
  git push
)

对于某些 shell(包括 bash、ksh93、mksh 和 bosh,但不包括 dash、zsh 或 yash),您也可以"${*-square-this-commit}"在此处使用。

为了完整起见,在 中bash,要连接具有任意字符串的数组(相当于 zsh 的joined=${(ps[$sep])array}),您可以执行以下操作:

IFS=
joined="${array[*]/#/$sep}"
joined=${joined#"$sep"}

(假设在区域设置中是有效文本;如果不是,则当 的内容与其余部分连接时最终形成有效文本时,$sep第二步可能会失败)。$sep


1 作为历史记录,在 Bourne shell 中,它们与 SPC 结合在一起,无论$IFS

答案2

实际上这似乎有效,但我不知道为什么:

  git commit -am "${args}" || { echo; }

相关内容