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?
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