Joining bash arguments into single string with spaces

I’m trying to join all of the arguments to a Bash function into one single string with spaces separating each argument. I also need to have the string include single quotes around the whole string.

Here is what I have so far…

$array=("<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e7c3a7">[email protected]</a>")
str="'"
for arg in "${array[@]}"; do
    let $str=$str+$arg+" "
done
let $str=$str+"'"

Obviously this does not work but I’m wondering if there is a way to achieve this?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I believe that this does what you want. It will put all the arguments in one string, separated by spaces, with single quotes around all:

str="'$*'"

$* produces all the scripts arguments separated by the first character of $IFS which, by default, is a space.

Inside a double quoted string, there is no need to escape single-quotes.

Example

Let us put the above in a script file:

$ cat script.sh 
#!/bin/sh
str="'$*'"
echo "$str"

Now, run the script with sample arguments:

$ sh script.sh one two three four 5
'one two three four 5'

This script is POSIX. It will work with bash but it does not require bash.

A variation: concatenating with slashes instead of spaces

We can change from spaces to another character by adjusting IFS:

$ cat script.sh 
#!/bin/sh
old="$IFS"
IFS='/'
str="'$*'"
echo "$str"
IFS=$old

For example:

$ sh script.sh one two three four       
'one/two/three/four'

Method 2

It’s easier than you think:

#!/bin/bash
array="${@}"

echo $array

chmod +x that, and run it:

$ ./example.sh --foo bar -b az 
--foo bar -b az

Method 3

update
Tl;dr, use

"'${array[*]}'"

To be clear, I don’t intend to replicate this answer. I just found there are minor differences to use @ and * to dereference all values from an array.

Under the hood, $* and [email protected] are all arrays, referring to the argv list.

From the question,

I’m trying to join all of the arguments to a Bash function into one single string with spaces separating each argument.

It has 2 sub-questions:

  1. concatenate the array input arguments into a string.
  2. pass the concatenated string as a single argument for the shell function.

First, concat array into a string,

array=("[email protected]")
str="'${array[@]}'"
# or
str="'${array[*]}'"
# or
str='"${array[*]}"'

Second, when you pass str to a function, let’s count the number of arguments that function received,

#!/usr/bin/env bash

arr=(a b c d)

function count_args() {
  echo '$#' $#
}

count_args "'${arr[@]}'"
count_args '"${arr[@]}"'
count_args "'${arr[*]}'"
count_args '"${arr[*]}"'

output is

$# 4
$# 4
$# 1
$# 1

only arr[*] wraps the array into 1 argument for the shell function, why?

Cite from How to use arrays in bash script, which I found it’s useful for me,

echo ${array[*]}
echo ${array[@]}

Both syntax let us access all the values of the array and produce the same results, unless the expansion it’s quoted. In this case a difference arises: in the first case, when using @, the expansion will result in a word for each element of the array.

Whereas using * will group the entire array into one single argument during expansion.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x