如何用rsync读取文本文件目录列表并完整迁移目录及内容?
问题与解决方案
问题描述
我在开发文件管理脚本时,想用rsync读取文本文件里的POSIX目录路径列表,把这些目录及其内容迁移到另一个位置。试了下面的命令:
rsync -avPh --no-R --files-from="/source/folders.txt" / /destination/folders --remove-source-files
甚至在末尾加了--include="*",但还是只复制了目录本身到目标位置,目录里的内容全被忽略了,而且--remove-source-files参数也没生效,最后源和目标都有一堆空目录,源文件根本没被处理。源和目标在同一个卷下,怎么解决?
补充:folders.txt的内容示例如下:
/volume1/Music/Media/Thee Milkshakes/Sing and Play 20 Rock and Roll Hits of the 50's and 60's (1991) /volume1/Music/Media/Tony Bennett/Playin' With My Friends- Bennett Sings the Blues (2001) /volume1/Music/Media/Thee Headcoats/The Kids Are All Square- This Is Hip! (1990) /volume1/Music/Media/Tiger Army/II- Power of Moonlite (2001) /volume1/Music/Media/T. Rex/Prophets, Seers & Sages- The Angels of the Ages (1968) /volume1/Music/Media/Ted Leo and the Pharmacists/Mo' Living (2007) /volume1/Music/Media/Ted Leo and the Pharmacists/tej leo(!), Rx + pharmacists (1999) /volume1/Music/Media/Ted Leo and the Pharmacists/Tell Balgeary, Balgury Is Dead (Plus Solo!) (2003) /volume1/Music/Media/Teenage Fanclub/Sparky's Dream (1995) /volume1/Music/Media/Teenage Fanclub/Words of Wisdom & Hope (2002) /volume1/Music/Media/Teenage Fanclub/God Knows It's True (1990)
解决办法
问题出在--files-from和--no-R的组合逻辑上:当你指定目录路径到files-from时,rsync默认只会处理这个目录条目本身,不会递归抓取其内容,加上--no-R还会剥离路径结构,导致内容无法被匹配到。
方案1:保留原路径层级迁移
如果你希望目标目录里保留原路径的完整层级(比如/destination/folders/volume1/Music/Media/...),直接去掉--no-R参数即可:
rsync -avPh --files-from="/source/folders.txt" --remove-source-files / /destination/folders
这个命令会让rsync按照folders.txt里的完整路径,递归复制每个目录下的所有内容,同时删除源端已复制成功的文件。
方案2:仅迁移目录(不含上层路径)
如果不想保留原完整路径,只需要把每个目录的内容直接放到目标根目录下的同名文件夹里,用循环遍历的方式更可靠:
while IFS= read -r dir_path; do # 复制目录下所有内容到目标目录的同名文件夹 rsync -avPh --remove-source-files "$dir_path"/ /destination/folders/"$(basename "$dir_path")"/ # 复制完成后删除源空目录 rmdir "$dir_path" done < "/source/folders.txt"
$(basename "$dir_path")会提取目录的最后一级名称,确保目标目录和源目录同名--remove-source-files仅删除源端的文件,rmdir负责清理复制后的空目录;如果要彻底删除源目录(包括可能残留的子目录),可以把rmdir换成rm -rf "$dir_path",但建议先测试确认复制无误再使用。
注意事项
--remove-source-files只对rsync成功复制的文件生效,不会自动删除源目录,需要手动清理- 因为源和目标在同一卷下,rsync会用硬链接优化传输,但不影响迁移逻辑
- 执行命令前建议先加上
--dry-run参数(比如rsync -avPh --dry-run ...),模拟执行过程,确认路径和内容正确后再正式运行
内容的提问来源于stack exchange,提问作者DasKraut
相关产品推荐
相关产品推荐

