Вы можете использовать nftw (3) , чтобы собрать все пути, а затем зацикливаться на mkdir (2) & rename (2) . nftw
использует opendir (3) , readdir (3) , closedir
, stat (2) (который вы можете использовать напрямую).
В недавней реализации C ++ 17 вы можете использовать <filesystem>
Если какой-то другой процесс записывает в подкаталоги, у вас могут быть проблемы (как, вероятно, mv
).
Возможно, выполнение /bin/mv
(этот путь к файлу стандартизирован POSIX) в другом процессе может быть проще.
Могут возникнуть проблемы, если /testdir
и /testdest
находятся в различных файловых системах (и точках монтирования), поскольку rename (2) работает только в одной файловой системе. mv
знает, как с этим справиться (в этом случае он копирует файлы перед удалением источника). Кроме того, некоторые из подкаталогов /testdir
могут быть точками монтирования и т. Д.
Если /testdir/
и /testdest/
находятся в одной и той же файловой системе и нет точек монтирования под /testdir
, вы можете просто выполнить цикл с opendir
, readdir
, closedir
, пропустить .
и ..
записей, создайте для каждой записи каталога соответствующие полные пути источника и назначения и используйте rename
для них.
Конечно, mv
является свободным программным обеспечением, в GNU coreutils
, и вы можете изучить его исходный код (он не так прост, как вы могли бы подумать, поскольку он обрабатывает угловые случаи). Вы также можете использовать strace (1) , чтобы понять, какие системные вызовы (перечислены в syscalls (2) ) задействованы какой-то командой или процессом mv
.