2

I want to join an array of strings on the string "%2C+". My shell script launch looks like this.

#!/bin/bash

function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }

selectQuery=$(join_by "%2C+" $1)
echo selectQuery

But when I run ./download-data $("state_code" "county_code"), I get this error in the terminal: bash: state_code: command not found.

I need to pass the argument as an array since I plan to pass more arrays later on. Something like ./download-data $("state_code" "county_code") $("more" "string").

3
  • 2
    There is no such thing as an array literal in bash; x=(a b) is a special form of the assignment statement. $(...) is a command substitution. Commented Apr 26, 2018 at 4:51
  • 3
    There are also no array values in shell. A name with the array attribute set allows syntax that simulates some aspects of a traditional array, but any expansion still only produces one or more distinct words, not a first-class value that contains all the array elements. Commented Apr 26, 2018 at 4:53
  • @Username : Since arrays are not "first class citizens" in bash, you can't pass them to a bash function. You could pass the name of a variable holding an array to the function, and then use, for instance, eval, but this is ugly. For me, this would be the point where I would think of replacing bash by a programming language which is better suitable for your application. Commented Apr 26, 2018 at 8:42

1 Answer 1

2

Make your script accept multiple strings in separate arguments:

#!/bin/bash

function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }

selectQuery=$(join_by "%2C+" "$@")
echo "$selectQuery"

and then run it with multiple arguments:

./download-data "state_code" "county_code"
Sign up to request clarification or add additional context in comments.

8 Comments

Sorry, I should clarify: I need to pass an array since I plan to pass multiple arrays in the future as I modify this script.
You can't: arguments are always a single list of strings. Do like find, parallel and others and designate a certain word as your separator. Then run e.g. ./download-data array1 array1 -- array2 array2. Alternatively, do like gcc and run ./download-data "array1 array1" "array2 array2" and split the strings yourself
Or give the length of each array followed by its elements. You'd run it like ./download-data "${#array1[@]}" "${array1[@]}" "${#array2[@]}" "${array2[@]}", and if array1 had two elements and array2 had four, it'd be like running ./download-data 2 array1elem0 array1elem1 4 array2elem0 array2elem1 array2elem2 array2elem3.
@Username Probably, but how you need to change it depends on what you're actually trying to do. What does it do differently with multiple arrays vs a single array?
@Username But what would you do with them? If you're just going to append them together, then it doesn't matter where one ends and the next begins. If you're doing something else... it'll depend on what that something else is.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.