我有一个主目录a,在各个子目录中有高分辨率图像(大约100Gb)。我有一个选择,这些图像(相同的文件名)是较低的分辨率在另一个目录B与不同的子目录(几千个文件)。
我希望能够获得相同目录B结构的副本,但替换为高分辨率版本。分辨率的代理可以是文件大小,因为目录A中只有一个匹配项。
从问题来看,为什么需要考虑脚本中的文件大小或分辨率有些不清楚。我将假设(1)在A
和B
下的整个(子)目录结构中文件名是唯一的;(2)A
总是包含相同或更高分辨率的图像,其中一些图像在B
下具有缩略图(通过文件名匹配)。大纲可以如下所示:
replace_files_by_name() {
local -r dir_A="$1" # full size ("source")
local -r dir_B="$2" # thumbnails ("index")
local -r dir_C="$3" # full size copy by index ("destination")
local path
# Create an index of file names and paths under $dir_A
local -A path_index # maps file names to paths under $dir_A
while IFS= read -r path; do
path_index["${path##*/}"]="$path"
done < <(find "$dir_A" -type f)
# Make a recursive copy of $dir_B called $dir_C.
echo cp -a --reflink "$dir_B" "$dir_C"
cp -a --reflink "$dir_B" "$dir_C"
# Replace each file under $dir_C with its counterpart from $dir_A.
find "$dir_C" -type f | while IFS= read -r path; do
echo cp -a --reflink "${path_index["${path##*/}"]}" "$path"
cp -a --reflink "${path_index["${path##*/}"]}" "$path"
done
}
旁注0:如果您有一个过时的文件系统,那么您将不得不放弃--reflink
,这将付出巨大的性能和空间代价。这就是为什么最好使用功能齐全的文件系统(至少具有CoW-capable (CoW == Copy on Write))。(例如Btrfs或ZFS)
旁注1:我的大纲跳过了所有错误检查,需要进行相应的调整。(例如,如果在A
下找不到C
(B
)中的文件,该怎么办?)
现在让我们测试解决方案:
set -eu
mkdir -p ~/tmp/test
cd ~/tmp/test
# Create directories A and B and 5 different subdirectories in each.
mkdir -p A/{1..5}/ B/{a..e}/
# Place a file in each subdirectory.
# A and B contain different subdirectory names but same file names.
files=('one' 'two' 'three' 'four' 'five')
for dir in A B; do
subdirs=("${dir}/"*)
((${#subdirs[@]} == ${#files[@]}))
for ((i = 0; i < ${#files[@]}; ++i)); do
touch "${subdirs[i]}/${files[i]}"
done
done
##############################
replace_files_by_name A B C ##
##############################
rm -Rf ~/tmp/test # cleanup
这个↑↑↑将输出(并执行)以下操作:
cp -a --reflink B C
cp -a --reflink A/1/one C/a/one
cp -a --reflink A/2/two C/b/two
cp -a --reflink A/3/three C/c/three
cp -a --reflink A/4/four C/d/four
cp -a --reflink A/5/five C/e/five