1

I want to zip file.txt and file with spaces.txt. I need to keep them in one variable. I can concat these string like this:

files="$files \"$newfilename\""

Then I have all the file names in one variable, separated by space and each one covered with quotation marks. "file.txt" "file with spaces.txt"

so I need to zip them now. However If I do:

tar czf output $files

then bash will produce:

tar czf output '"file.txt."' '"file' with 'spaces.txt"'

If I do

tar czf output "$files"

then bash will do:

tar czf output '"file.txt." "file with spaces.txt"'

In first case, bash insert a apostrophe after and before each word, in the second case, tar takes both files as one name. What should I do to produce tar czf "file.txt" "file with spaces.txt" if I have exactly this string in $files variable?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Dan
  • 109
  • 4
  • 13

1 Answers1

2

Using a variable for storing multi word entries that are independent. Use an array and quote the file-names properly, so the names with spaces are preserved

declare -a files=()
files=("file.txt")
files+=("file with spaces.txt")

The +=() is used to append elements to an existing array. Now expanding the array is what you need to pass the list to zip

tar czf output "${files[@]}"

Regarding OP's question on the context between doing files=() and declare -a files=(). They are probably the same thing and work in the same context of initializing indexed arrays. But a noticeable difference happens when you do declare -a files without the () part. Because declare -a does not re-initialize an array which is already defined but =() empties it. Refer to the example below

prompt> files=()
prompt> files+=(a "new word")
prompt> files+=("another word")
prompt> echo "${files[@]}"
a new word another word

Now doing files=() would empty the existing the array completely,

prompt> files=()                   # array completely emptied now
prompt> echo "${files[@]}"
                                   # empty result

But with the same content as previously and doing

prompt> echo "${files[@]}"
a new word another word
prompt> declare -a files           # an existing array is not emptied
prompt> echo "${files[@]}"
a new word another word
Inian
  • 80,270
  • 14
  • 142
  • 161