Just one file echoed from an array of files
It's Bash
feature described in man bash
:
Referencing an array variable without a subscript is equivalent to referencing the array with a subscript of 0.
If you want to print all members of files
array:
echo "${files[@]}"
Also described in man bash
:
${name[@]} expands each element of name to a separate word.
$files
and ${files[0]}
is equivalent when files
is a list such as the one you have in your question.
Note that "source_path/${files[@]}"
only puts source_path/
before the first element of the list.
To modify the list in such a way that each element is prefixed by some path, you can do
files=( ... your list of files ... )
for element in "${files[@]}"; do
files=( "${files[@]:1}" "source_path/$element" )
done
cp "${files[@]}" destanation_path
or, you could just cd
to source_path
before doing the cp
, or add the path to the actual names at the same time as you assign the values in the list from the start.
As others have pointed out, $files
only expands to the first element of the array, and "source_path/${files[@]}"
only attaches "source_path/" to the first element. But there's a relatively simple way to get all elements, with a path prepended to each:
cp -a "${files[@]/#/source_path/}" "/destanation_path"
This combines the all-elements expansion ([@]
) with a substitution. /#
means "replace at beginning of string", then the empty string to replace, then /
to delimit the replacement, then "source_path/" as the thing to replace (/add). This attaches the source path to each element, and doesn't get confused by funny characters in the elements like some versions do.
Note that in the above example, "source_path/" has a slash at the end but not the beginning; the "/" right before it is a delimiter. If it started with a slash and contained more slashes, like "/source/path/", it'd still work:
cp -a "${files[@]/#//source/path/}" "/destanation_path"