仅从一组文件中回显一个文件

仅从一组文件中回显一个文件

cp我尝试使用数组将 2 个或多个文件从一个目录复制到另一个目录。
我执行了:

files=(
    LocalSettings.php
    robots.txt
    .htaccess
    ${domain}.png
    googlec69e044fede13fdc.htm
)

文件名用表格缩进;

我的目标是之后执行:

cp -a "source_path/${files[@]}" "/destanation_path"

我的问题是,在测试变量本身时,
echo $files仅返回第一个文件名LocalSettings.php,而不返回完整的文件列表。
你会如何解释这一点?
有关的:多线方式 cp;

答案1

Bash功能描述如下man bash

引用不带下标的数组变量相当于引用下标为 0 的数组。

如果要打印files数组的所有成员:

echo "${files[@]}"

还描述于man bash

${name[@]} 将 name 的每个元素扩展为一个单独的单词。

答案2

$files当是一个列表(例如您问题中的列表)时,它${files[0]}是等效的。files

请注意,"source_path/${files[@]}"仅放置source_path/在列表的第一个元素之前。要以每个元素都以某个路径为前缀的方式修改列表,您可以这样做

files=( ... your list of files ... )

for element in "${files[@]}"; do
    files=( "${files[@]:1}" "source_path/$element" )
done

cp "${files[@]}" destanation_path

或者,您可以cdsource_path执行 之前cp,或者在从一开始就在列表中分配值的同时添加实际名称的路径。

答案3

正如其他人指出的那样,$files仅扩展到数组的第一个元素,并且"source_path/${files[@]}"仅将“source_path/”附加到第一个元素。但是有一种相对简单的方法来获取所有元素,并在每个元素前面添加一个路径:

cp -a "${files[@]/#/source_path/}" "/destanation_path"

这将全元素展开 ( [@]) 与替换结合起来。/#表示“在字符串开头替换”,然后是要替换的空字符串,然后/是分隔替换,然后是“source_path/”作为要替换的内容(/add)。这会将源路径附加到每个元素,并且不会像某些版本那样被元素中的有趣字符混淆。

请注意,在上面的示例中,“source_path/”末尾有斜杠,但开头没有斜杠;前面的“/”是分隔符。如果它以斜杠开头并包含更多斜杠,例如“/source/path/”,它仍然有效:

cp -a "${files[@]/#//source/path/}" "/destanation_path"

答案4

您还可以尝试以下代码片段:

IFS=$'\n'
cp -a $( printf "source_path/%s\n" "${files[@]}" ) /destination_path/

它还应该适用于带空格的文件名。

相关内容