我有这个脚本,它从主文件夹递归复制 csv 中列出的文件。脚本的复制方面效果很好。但是,我现在想添加一些错误检测功能。我在下面添加的“if”循环无法按我的意愿工作。我已将一个假文件添加到我的 csv 列表中以进行测试,并且脚本报告所有文件均已成功复制,即使其中一个文件不存在。有人可以建议我如何让脚本报告尚未从 csv 成功找到/复制的文件并指定文件名吗?编辑 ** 由于 CSV 中列出了 4000 多个文件,我希望脚本在脚本末尾打印任何复制失败的摘要,而不是针对在此过程中复制的每个文件。这将使识别/总结任何问题变得更加容易。
while IFS=, read -r file rest
do
find $sourcefolder -name "${file}" -exec cp '{}' $destfolder \;
done < $csv
if [ $? -eq 0 ]
then
echo "All files from CSV copied succesfully"
else "File from CSV not copied as not found"
fi
答案1
返回的错误代码find
与是否找到任何文件无关。如果命令本身运行失败,它只会返回失败代码。您正在寻找的是这样的:
while IFS=, read -r file rest
do
find $sourcefolder -name "${file}" -exec cp '{}' $destfolder \;
## Check if the file was copied
[[ -e "$destfolder/$file" ]] || echo "File $file was not copied"
done < "$csv"
echo "Finished"
这样,脚本将告诉您任何未成功复制的文件。
如果您只想在脚本末尾打印错误,可以将错误的文件名保存在变量中,并在循环完成后打印它:
while IFS=, read -r file rest
do
find "$sourcefolder" -name "$file" -exec cp '{}' "$destfolder" \;
## Check if the file was copied
[[ -e "$destfolder/$file" ]] || badfiles=$(printf "%s\n%s" "$file" "$badfiles")
done < "$csv"
## Check if all the files were correctly copied
if [[ -z "$badfiles" ]]; then
echo "All files were succesfuly copied."
else
printf 'Some files were not copied:\n%s\n' "$badfiles"
fi
您还可以扩展它以避免覆盖同名的文件:
while IFS=, read -r file rest
do
find "$sourcefolder" -name "$file" -print0 |
while IFS= read -d '' -r filepath; do
c="";
while [[ -e "$destfolder/$file$c" ]]; do
((c++))
done
cp "$filepath" "$destfolder/$file$c"
done
## Check if the file was copied
[[ -e "$destfolder/$file" ]] || badfiles=$(printf "%s\n%s" "$file" "$badfiles")
done < "$csv"
## Check if all the files were correctly copied
if [[ -z "$badfiles" ]]; then
echo "All files were succesfuly copied."
else
printf 'Some files were not copied:\n%s\n' "$badfiles"
fi
如果 csv 中的文件名可以包含换行符,此操作将会失败。如果可能的话,请将第一个while
循环更改为:
while IFS= read -d"," -r file rest; do ...
但请注意,如果 csv 的任何行只包含文件名(因此没有逗号),则此操作将会失败。你不能同时使用这两种方法,如果你可以有没有逗号的行,请使用第一个版本,如果你可以有带换行符的文件名,请使用第二个版本。
答案2
你的循环是不正确的,因为你什么也没做
rest
作为特登建议在每次复制后检查,而不是在循环后检查一次
- 否定文件检查的存在,以获得正确的注释
- 并注意特登的警告,如果源树中有相同名称的文件,则您在目标中只会获得一份副本。
尝试这个,
while read -d, -r file
do
find $sourcefolder -name "${file}" -exec cp '{}' $destfolder \;
## Check if the file was copied
[[ ! -e "$destfolder/$file" ]] && echo "File $file was not copied"
done < "$csv"
echo "Finished"
更新:
如果您的 CSV 是这样的,则此解决方案有效
fileA,fileB,fileC,fileD, ...
但是,既然您说 terdon 的解决方案有效,您的文件必须如下所示
fileA,valueA1,valueA2,valueA3
fileB,valueB1,valueB2,valueB3
fileC,valueC1,valueC2,valueC3
fileD,valueD1,valueC2,valueD3
文件名之后的其余行将被简单地丢弃。