在bash中连接超出前N个的剩余参数

时间:2016-05-25 02:49:18

标签: string bash loops

之前我没有写过任何bash脚本。这是我需要做的。

我的脚本将使用一组字符串参数运行。 stings的数量将超过8.我将不得不连接字符串9及之后的字符串,并从那些字符串中生成一个字符串。像这样......

myscript s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 ....(总未知)

在脚本中,我需要这样做......

new string = s9 + s10 + ...

我正在尝试这样的事情......(来自网络搜索)。

 array="${@}"
 tLen=${#array[@]}
 # use for loop  to read string beyond 9
 for (( i=8; i<${tLen}; i++ ));
 do
   echo ${array[$i]}  --> just to show string beyond 9
 done

不工作。如果i = 0,则打印出来。这是我的意见。

./ tastest 1 2 3 4 5 6 7 8 A B C

我期待打印A B C.最后我将不得不制作ABC。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

它应该比问题中的循环简单得多:

shift 8
echo "$*"

失去论据1-8;将所有其他参数作为单个字符串打印,并使用单个空格分隔参数(并保留参数中的空格)。

或者,如果您需要变量,那么:

nine_onwards="$*"

或者如果你不能丢弃主shell进程中的前8个参数:

nine_onwards="$(shift 8; echo "$*")"

你可以检查至少有9个参数,当然,如果没有则抱怨。或者你可以接受一个空字符串 - 没有错误。

如果参数必须连接起来没有空格(如问题修正案中所述),那么你必须与$IFS一起玩:

nine_onwards="$(shift 8; IFS=""; echo "$*")"

如果我正确地解释了下面这个答案的注释,那么你想要将前8个参数保存在8个单独的简单(非数组)变量中,然后在另一个简单变量中将参数9向前保存,之间没有空格。参数值。

这是可以接受的:

var1="$1"
var2="$2"
var3="$3"
var4="$4"
var5="$5"
var6="$6"
var7="$7"
var8="$8"
var9="$(shift 8; IFS=""; echo "$*")"

这些名称不必与那些名称密切相关。你可以使用:

teflon="$1"
absinthe="$2"
astronomy="$3"
lobster="$4"
darkest_peru="$5"
mp="$6"
culinary="$7"
dogma="$8"
concatenation="$(shift 8; IFS=""; echo "$*")"

您也不必按此顺序执行此操作;任何序列(排列)都会很好。

请注意,在问题中,你有:

array="${@}"

尽管有名称,但它创建了一个包含参数的简单变量。要创建数组,必须使用这样的括号,其中空格是可选的:

array=( "$@" )

答案 1 :(得分:2)

# Create a 0-index-based copy of the array of input arguments.
# (You could, however, work with the 1-based pseudo array $@ directly.)
array=( "${@}" )

# Print a concatenation of all input arguments starting with the 9th
# (starting at 0-based index 8), which are passed *individually* to
# `printf`, due to use of `@` to reference the array [slice]
# `%s` as the `printf` format then joins the elements with no separator 
# (and no trailing \n).
printf '%s' "${array[@]:8}"

# Alternative: Print the elements separated with a space:
# Note that using `*` instead of `@` causes the array [slice] to be expanded
# to a *single* string using the first char. in `$IFS` as the separator,
# which is a space by default; here you could add a trailing \n by using
# '%s\n' as the `printf` format string.
printf '%s' "${array[*]:8}"

请注意,array="${@}" 创建一个数组 - 它只是创建一个字符串标量,包含由分隔的输入数组元素的串联(不可避免)空间每个;要创建数组,必须将其括在(...)

要根据您在follow-up question中的请求,从以双引号括起的第9个开头的参数创建以空格分隔的单个字符串,请使用以下命令:

printf -v var10 '"%s"' "${array[*]:8}"

根据您的问题$var10中的最后一个示例调用将包含文字"A B C"包括双引号。

至于将参数1到8分配给各个变量。:

Jonathan Leffler's helpful answer显示如何在单个变量中保存前8个参数。

这是一种基于给定名称前缀和序列号创建单个变量的算法替代方案:

n=8  # how many arguments to assign to individual variables

# Create n 'var<i>' variables capturing the first n arguments.
i=0  # variable sequence number
for val in "${array[@]:0:n}"; do
  declare "var$((++i))=$val" # create $var<i>, starting with index 1
done

# Print the variables created and their values, using variable indirection.
printf "\nvar<i> variables:\n"
for varName in "${!var@}"; do
  printf '%s\n' "$varName=${!varName}"
done

答案 2 :(得分:-1)

你很接近 - 这样的事情会起作用:

array=( ${*} )
# use for loop  to read string beyond 9
for (( i=8; i<${#array[*]}; i++ ));
do
   echo -n ${array[$i]}
done