2

I wrote the following code:

join(){
        IFS="$1"
        shift
        echo "$*"
}

FILES=(/tmp/*)
SEPARATED_FILES=$(join , ${FILES[*]})
echo $VAR

And it prints the comma separated lists of files in /tmp just fine. But I would like to refactor it and eliminate the tmp global variable FILES which is an array. I tried the following:

SEPARATED_FILES=$(join , ${(/tmp/*)[*]})
echo $VAR

But it prints the following error:

line 8: ${(/tmp/*)[*]}: bad substitution    

1 Answer 1

2

Yes! You can avoid it by doing pass the glob as directly an argument to the function. Note that, the glob results are expanded by the shell before passing to the function. So pass the first argument as the IFS you want to set and the second as the glob expression you want to use.

join , /tmp/*

The glob is expanded to file names before the function is being called.

join , /tmp/file1 /tmp/file2 /tmp/file3

A noteworthy addition to the above would be to use nullglob option before calling the function. Because when the glob does not produce any results, the un-expanded string can be safely ignored.

shopt -s nullglob
join , /tmp/*

and in a command substitution syntax as

fileList=$(shopt -s nullglob; join , /tmp/*)

Couple of takeaways from your good effort.

  1. Always apply shell quoting to variables/arrays unless you have a reason not to do so. Doing so preserves the literal value of the contents inside and prevents Word-Splitting from happening
  2. Always use lower case names for user-defined variable/function and array names
Sign up to request clarification or add additional context in comments.

Comments

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.