我正在寻求批处理文件的帮助,这些批处理文件允许我将特定类型的所有文件(例如 *.PDF)移动到新文件夹。但是,我希望在过程中包含一些我不太了解的功能(我不是程序员)(请参阅我消息末尾的问题)。我在网上搜索了各种解决方案,但还没有找到可以满足我需求的应用程序。所以,我来这里寻找成熟的解决方案。我发现我可以使用 ROBOCOPY 将所有文件放入目录中,方法是:
@echo off
set source="R:\Users\Public\"
set destination="R:\Users\Public\All_PDF_Files\"
ROBOCOPY %source% %destination% *.pdf /S /R:1 /W:1 /NDL /XD OutputFolderfor /r %source in (*) do @copy "%destination" .
但我无法确定如何操作,即事后将目录扁平化并将所有文件放在一个文件夹中。我看过一两篇帖子(一篇来自用户 Max,他编写了一个批处理文件来扁平化目录,这几乎就是我需要的。因此从他的批处理文件开始……假设我有一个目录树,其中仅包含保存 PDF 文件的目录和子目录……以及一个已识别的目标文件夹……Max 给出了以下内容……
来自 Max Below...
我最近不得不解决这个问题,我想将许多文件从层次结构移动到单个文件夹,这些文件彼此同名,并且我希望仍然使层次结构扁平化,而不会覆盖它们。我所做的就是编写一个脚本来移动文件,但使用名称中的旧层次结构路径重命名它,例如:源文件:
C:\files\somefiles\file.txt C:\files\otherfiles\file.txt 目标是 C:\newdir\ 文件创建为 C:\newdir\somefiles-file.txt C:\newdir\otherfiles-file.txt 这里是代码,批处理文件 1 浏览文件,批处理文件 2 重命名并移动它们(如果您想保留源,也可以复制:
@echo off
for /r %%f in (*.*pr) do @renameandmovefilespart2.bat "%%f" "%%~ff" "%%~xf"
重命名并移动文件第 2 部分.bat
@echo off
Setlocal EnableDelayedExpansion
rem set the whole file path
set origWhole=%1
set origPathOnly=%2
set extension=%3
rem here you can set where the directory to hold the flattened hierarchy is
set destDir=c:\destinationDir\
rem set the directory to do a string replace
rem make this the starting directory, that you dont want in the newly renamed files
set startingDir=C:\starting\directory\
set nothing=
set slash=\
rem here you can set what the character to represent the directory indicator \ in the new files
set reaplcementDirectoryCharacter=--
set quote="
rem cut out the starting part of the directory
call set newname=%%origWhole:!startingDir!=!nothing!%%
rem replace slashes with new character
call set newname=%%newname:!slash!=!reaplcementDirectoryCharacter!%%
rem remove quotes
call set newname=%%newname:!quote!=!nothing!%%
rem @echo shortened: %newname%
rem @echo source path: %origPathOnly% newPath: %startingDir%
rem @echo extension: %extension%
rem rename the files
ren %origWhole% %newname%
rem prepare to move the file, clean up the source path
call set origPathOnly=%%origPathOnly:!quote!=!nothing!%%
move "%origPathOnly%%newname%" "%destDir%"
问题:
1.) 我不用在文件名前面加上源文件夹,而是如何在文件名后面加上源文件位置?我是否只需将“%%~ff”“%%~xf”重写为“%%FF~”“%%XF~”
2.) 我不想移动文件我只想覆盖源文件注意:如果需要我可以删除源文件!
还有其他问题吗?
3.) (*.*pr) 在 Max 的第一个批处理文件中起什么作用?
4.) Max 在上面第 2 批中说的这些 (第 9 行) rem 将此设为起始目录,您不希望在新重命名的文件中出现 (第 10 行) “rem 将此设为起始目录,您不希望在新重命名的文件中出现” 是什么意思?他只是表示源目录中的一个子目录吗?
答案1
如果您不受批处理文件的限制,这里有一个 PowerShell 解决方案:
# Setup source and destination paths
$Src = 'c:\source'
$Dst = 'c:\destination'
# Wildcard for filter
$Extension = '*.pdf'
# Get file objects recursively
Get-ChildItem -Path $Src -Filter $Extension -Recurse |
# Skip directories, because XXX.PDF is a valid directory name
Where-Object {!$_.PsIsContainer} |
# For each file
ForEach-Object {
# If file exist in destination folder, rename it with directory tag
if(Test-Path -Path (Join-Path -Path $Dst -ChildPath $_.Name))
{
# Get full path to the file without drive letter and replace `\` with '-'
# [regex]::Escape is needed because -replace uses regex, so we should escape '\'
$NameWithDirTag = (Split-Path -Path $_.FullName -NoQualifier) -replace [regex]::Escape('\'), '-'
# Join new file name with destination directory
$NewPath = Join-Path -Path $Dst -ChildPath $NameWithDirTag
}
# Don't modify new file path, if file doesn't exist in target dir
else
{
$NewPath = $Dst
}
# Copy file
Copy-Item -Path $_.FullName -Destination $NewPath
}