![将文件从 1 个大驱动器移动到 2 个小驱动器](https://linux22.com/image/943594/%E5%B0%86%E6%96%87%E4%BB%B6%E4%BB%8E%201%20%E4%B8%AA%E5%A4%A7%E9%A9%B1%E5%8A%A8%E5%99%A8%E7%A7%BB%E5%8A%A8%E5%88%B0%202%20%E4%B8%AA%E5%B0%8F%E9%A9%B1%E5%8A%A8%E5%99%A8.png)
我正在尝试编写一个脚本,将文件从一个大驱动器移动到两个较小的驱动器 - 我认为如果交替进行会更好。因此,将第一个文件移动到驱动器 A,将第二个文件移动到驱动器 B,将第三个文件移动到驱动器 A 等等......它们是否按顺序进行实际上并不重要,可以随机选择(我只是认为这样会更容易) - 更重要的是我有 2 个驱动器,其中包含相似数量的文件。或者是否有命令可以将??TB 从一个驱动器复制到另一个驱动器??或复制到驱动器已满。
操作系统是 Ubuntu 18.04.6 LTS
这是导致问题的原始脚本部分。它开始将数据复制到驱动器 1 和驱动器 2,但随后只复制到驱动器 1。因此,最终一个驱动器已满,而另一个几乎为空。
DATA=/home/data
DATADRIVES=(/media/Drive1/data /media/Drive2/data)
getLowest () {
LOWEST=${DATADRIVES[0]}
for DRIVE in ${DATADRIVES[@]}; do
if [[ $(du $DRIVE) < $(du $LOWEST) ]]; then
LOWEST=$DRIVE
fi
done
}
echo "Copying data from Drives"
echo "DRIVES: ${DATADRIVES[@]}"
FILESTOCOPY=$(find "$DATA"/* -type f)
for F in ${FILESTOCOPY[@]}; do
getLowest
echo "Now copying to $LOWEST"
rsync --progress -S $F $LOWEST
done
答案1
如果将任务分为两个步骤,首先,将较大驱动器的文件名划分并保存为两个文件。为了在不同文件之间切换,使用一个简单的模数,它给出0
、1
、0
,1
数字用于解析用于文件名的文件,例如0
解析names_0.txt
等等。文件列表应该只包含所有结束节点(文件、链接和空文件夹)并且没有起点。对于最后一部分,cpio
使用它来代替移动文件(我相信复制不会像 mv 那样给心脏带来太大的压力)。使用相同的原理来解析 的目标cpio
。
#!/bin/bash
a=0
b=$PWD
c=$b/source
declare -A A=( \
[0]=$b/names_0.txt [1]=$b/names_1.txt [$b/names_0.txt]=$b/mnt/target_0 [$b/names_1.txt]=$b/mnt/target_1 \
)
rm -f "${A[0]}" "${A[1]}"
# 0,1,0,1
while IFS= read -rd ''; do # ⌄
printf %s\\0 "$REPLY" >> "${A[$((++a % 2))]}"
# ⌃
# $b/names_0.txt, $b/names_1.txt
done < <(find "$c" \( \( -type d -empty \) -o ! -type d \) -printf %P\\0 | sort -zV)
# $b/names_0.txt, ...
# ⌄
for d in "${A[0]}" "${A[1]}"; do
# $b/mnt/target_0
# ⌄
cpio -0 -pvdm -D "$c" "${A[$d]}" < "$d"
done # ⌃
# $b/names_0.txt
我使用一个简单的安装脚本来生成一个测试示例:
#!/bin/bash
a=0
for i in source/{a..z}/{0..20}; do
install -D /dev/null $i/file_$((++a)).txt
done
mkdir -p mnt/target_{0..1}