将具有特定(相同)名称的子文件夹复制到目标
Posted
技术标签:
【中文标题】将具有特定(相同)名称的子文件夹复制到目标【英文标题】:Copy subfolders with specific (same) name to destination 【发布时间】:2020-09-23 07:29:08 【问题描述】:围绕以下问题思考 - 也试图说明我试图实现的目标。
源包含名为“import”的子文件夹,其中包含文件和/或文件夹 - (仅)此“import”文件夹应以新的个人名称复制到目标目录,因为只能有一个同名文件夹当然。
.Source
├── FolderA
│ └── import
│ └── Attachment
│ └── log
│
├── FolderB
│ └── import
│ └── log
│
├── FolderC
│ └── import
│ └── Attachment
│ └── log
.
.Destination
├── import27526
│ └── Attachment
│
├── import96385
│
├── import52987
│ └── Attachment
我尝试在 CMD 中使用 FOR 和 xcopy 或 robocopy 解决这个问题,创建随机目标目录。
for /f "delims=" %%A in ('dir /a:d /b /s "import"') do (xcopy /y /i /S "%%A" "C:\temp\%%~nxA%random%")
不幸的是,它不起作用,因为来自各种“导入”源文件夹中的所有数据都被复制到单个目标目录而不是单个目标目录中。
非常感谢任何帮助!
【问题讨论】:
您发布的代码不是cmd 命令行,而是batch-file 命令行。请重新审视问题,调整代码和/或标签以匹配,谢谢。另外,正如您已经说过您不希望有两个同名目录,是什么让您认为%RANDOM%
永远不会输出与现有目录匹配的数字字符串?将它们命名为FolderA_import
、FolderB_import
、FolderC_import
等会更有意义。
嗨!感谢您的澄清,我更改了标签。复制的文件夹将在几分钟内从目标目录中处理和删除,所以我认为相同随机值的机会非常小。但是,是的,我同意以您描述的模式命名文件夹确实很有意义。
你的代码片段的核心问题——除了随机数的可能重复——是随机数缺少delayed expansion...
【参考方案1】:
根据我的评论和您的回复,以下batch-file 应该适合您:
@For /D %%G In (".Source\*") Do @%__AppDir__%Robocopy.exe "%%G\import" ".Destination\%%~nxG_import">NUL
来自cmd:
For /D %G In (".Source\*") Do @%__AppDir__%Robocopy.exe "%G\import" ".Destination\%~nxG_import">NUL
【讨论】:
嗨!首先谢谢你!!我在 robocopy 命令中添加了 /S,因此“导入”目录中的子目录也被复制了,现在它可以按预期工作了! 这可能是明智的@Stefanski,我只是没有添加它,因为从这个声明中不清楚,“(仅)这个“导入”文件夹应该被复制到目标目录” .因此,我留下了所有选项,robocopy,供您根据需要包括在内。【参考方案2】:下面是 Powershell 中的一个简单代码,它复制文件夹及其内容,并在目标文件夹中添加一个数字。 是不是您正在寻找的东西?
下面的脚本是一次性的,如果你运行两次就会失败(数字将从 1 重新开始)。
如果您想多次运行它,您可以简单地添加 If-statement
来检查使用过的名称。
$source = "SOURCE PATH"
$destination = "DESTINATION PATH"
$foldername = "FOLDERNAME"
$number = 0
$folders = Get-ChildItem -Path $source -Recurse | Where-Object $_.Name -eq $foldername
Foreach ($folder in $folders)
$number++
Copy-Item -Path $folder -Destination $destination -Recurse
Rename-Item -Path "$destination\$foldername" -NewName "$foldername $Number"
【讨论】:
嗨!谢谢,我也尝试了您的 Power-Shell 解决方案 - 脚本似乎没有将源路径完全传递给 Copy-Item 命令。我得到: + CategoryInfo : ObjectNotFound: (C:\temp\import:String) [Copy-Item], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand - 所以它试图从目录中复制“import”我从执行脚本。但是随着 Compo 发布的解决方案正在运行,我已经很高兴了。只是想让你知道。 嗨!很高兴它成功了。关于脚本,您需要将路径上移一步,因为它使用递归(在下面的文件夹中搜索)。否则它不会找到任何东西,所以在你的情况下$source
应该是 "C:\Temp"
嗨!我确实在 $source 中使用了完整的源路径——但即便如此,它还是试图从“上一层”中选择“import-Folder”——所以当我使用 c:\copytest 作为 $source 并且结构是 C:\COPYTEST \AAA\import,错误消息将是 ObjectNotFound: (C:\COPYTEST\import:String)
你能把你的整个代码粘贴到下面吗?必须是其他关闭的东西
嗨!从 c:\script 代码执行脚本:$source = "C:\TESTCOPY" $destination = "C:\temp" $foldername = "import" $number = 0 $folders = Get-ChildItem -Path $source -Recurse | Where-Object $_.Name -eq $foldername Foreach ($folder in $folders) $number++ Copy-Item -Path $folder -Destination $destination -Recurse Rename-Item -Path "$destination\$foldername" -NewName "$foldername $Number" $
错误:复制项:找不到路径“C:\scripts\import”,因为它不存在。在 C:\scripts\testcopy.ps1:9 char:5【参考方案3】:
虽然用户Compo 的approach 可能是最聪明的解决方案,但我想提供一个脚本,将唯一随机数应用于目标目录中的子目录import*
:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=.\Source"
set "_TARGET=.\Destination"
set "_SUBDIR=import"
rem // Reset array variables:
for /F "delims==" %%E in ('2^> nul ^(set "$DIR[" ^& set "$RND["^)') do set "%%E="
rem // Build array of source sub-directories:
set /A "CNT=0"
for /D %%J in ("%_SOURCE%\*") do (
for %%I in ("%%~J\%_SUBDIR%") do (
set "ATTR=%%~aI" & set "ITEM=%%~fI"
setlocal EnableDelayedExpansion
if defined ATTR if "!ATTR:~,1!"=="d" (
for /F "delims=" %%E in ("$DIR[!CNT!]=!ITEM!") do (
endlocal & set "%%E"
)
set /A "CNT+=1"
) else endlocal
)
)
rem // Build array of unique random numbers:
set /A "CNT-=1"
for /L %%R in (0,1,%CNT%) do (
setlocal EnableDelayedExpansion
set /A "RND=(!RANDOM!<<16)+(!RANDOM!<<2)+!RANDOM!%%2"
for /F "delims=" %%E in ("$RND[!RND!_%%R]=%%R") do (
endlocal & set "%%E"
)
)
rem // Copy source sub-direcgtories to destination using random names:
setlocal EnableDelayedExpansion
set /A "CNT=0"
for /F "tokens=2 delims==" %%R in ('2^> nul set "$RND["') do (
> nul xcopy /Y /E /I "!$DIR[%%R]!" "!_TARGET!\!_SUBDIR!!CNT!"
set /A "CNT+=1"
)
endlocal
endlocal
exit /B
如果您对序列号感到满意,关于文件系统返回匹配子目录的顺序(在 NTFS 等现代系统文件中通常是字母),您可以改用此脚本:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=.\Source"
set "_TARGET=.\Destination"
set "_SUBDIR=import"
rem // Build array of source sub-directories:
set /A "CNT=0"
for /D %%J in ("%_SOURCE%\*") do (
for %%I in ("%%~J\%_SUBDIR%") do (
set "ATTR=%%~aI" & set "ITEM=%%~fI"
setlocal EnableDelayedExpansion
if defined ATTR if "!ATTR:~,1!"=="d" (
> nul xcopy /Y /E /I "!ITEM!" "!_TARGET!\!_SUBDIR!!CNT!"
endlocal & set /A "CNT+=1"
) else endlocal
)
)
endlocal
exit /B
【讨论】:
以上是关于将具有特定(相同)名称的子文件夹复制到目标的主要内容,如果未能解决你的问题,请参考以下文章
批处理 - 如何将文件类型 A 的文件从路径 A 的子文件夹 A 复制到路径 B 的子文件夹 A?
批处理文件以循环遍历文件夹并将文件夹和内容复制到具有相同文件夹名称的目录