0

What's a good way to concatenate all arguments of a function?

What I got at the moment is iterating over them and appending them consecutively:

func(){
concat=
for arg in "$@"
do
    concat=$concat$arg
done
echo $concat
}

I'd like to potentially do something like:

another_func() {
echo $(remove_spaces $@)
}
3
concat () (
    IFS=''
    printf '%s\n' "$*"
)

This function uses "$*" (the double quotes are important), which will expand to a single string with the values of the positional parameters (the arguments) concatenated with the value of the first character of $IFS as delimiter.

We set IFS to an empty string, which means "$*" would expand to all the arguments concatenated without a delimiter.

Also note that we protect the rest of the shell script from adopting the changed $IFS value by enclosing it in a subshell ( ... ) instead of the usual { ... }.

A call to this function could, in another function, look like

other_func () {
    printf '%s\n' "$( concat "$@" )"
}

or shorter, without actually calling the concat function:

other_func () {
    ( IFS=''; printf '%s\n' "$*" )
}

To delete all spaces in a list of arguments, use

printf '%s\n' "$*" | tr -d ' '

e.g.,

concat_delete_sp () {
    printf '%s\n' "$*" | tr -d ' '
}

Testing:

$ concat 1 2 3 "h h h" o o o
123h h hooo
$ concat_delete_sp 1 2 3 "h h h" o o o
123hhhooo
0

For a few-resources-fast-solution with an approach based on your second example:

func(){
  a=$@;echo ${a// /}
}

By this way you are removing absolutely all the spaces. But have in mind @kusalananda's approach if you plan to have arguments containing spaces.

  • This would produce the wrong results if any of the arguments contained a space. These spaces would also be deleted, so it's not really "concatenating the arguments". – Kusalananda Mar 22 at 11:46
  • @Kusalananda I agree but is the example the user asked for as the second example. I assumed he has it foreseen already – Juan Mar 22 at 11:50
  • Also note that you would want to double quote variable expansions to avoid issues when calling the function as e.g. func '*' – Kusalananda Mar 22 at 11:53
  • @Kusalananda I think that if that is the situation, the question should have more details. I assumed his goal is to keep it simple, fast and using the less amount of resources as possible for a very specific problem. If you assume more, you should ask for edit the question with more details – Juan Mar 22 at 11:59
0

In the zsh shell, you can use the j:separator: parameter expansion flag to join the elements of an array with an arbitrary separator. So you can do:

concat=${(j::)argv}

or

concat=${(j::)@}

to concatenate the elements of the $argv aka $@ array without having to modify a global parameter like $IFS.

If it's just to print the arguments, with Bourne-like shells, you can always do:

concat() {
  printf %s "$@" || return
  [ "$#" -eq 0 ] || printf '\n' # empty output if no argument
}

The printf builtin of bash and zsh can also store the result in a variable with:

printf -v variable %s "$@"

With the fish shell, you can use:

echo -s -- $argv

(it prints an empty line if $argv is an empty list).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.