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
或者,您可以cd
在source_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/
它还应该适用于带空格的文件名。