用于将子子文件夹向上移动一级的脚本(Batch或PowerShell)

时间:2014-02-26 01:32:16

标签: batch-file powershell

我在Stackoverflow上发现了一些类似的问题,在尝试解决方案之后,我的问题仍然没有解决。

这是我的目录结构:

  

D:\ XYZ \ Adam Jay \ Adam Jay \ files.txt

     

D:\ XYZ \ Adam Jay \ Adam Jay \ SomeFolder \

     

D:\ XYZ \ Adam Jay \ Adam Jay \ OtherFolder \ Some File.doc

     

D:\ XYZ \ Mary Poppins \ Mary Poppins \ myOtherFile.txt

我有大约2000个。

我的目标是按照上述结构简单地删除冗余的子子文件夹。手动,我只需剪切“sub-sub”文件夹“Adam Jay”并将其粘贴到XYZ中,在那里它将替换或合并上层“Adam Jay”(用它移动任何文件和文件夹)。

期望的结果:

  

D:\ XYZ \ Adam Jay \ files.txt

     

D:\ XYZ \ Adam Jay \ SomeFolder \

     

D:\ XYZ \ Adam Jay \ OtherFolder \ Some File.doc

     

D:\ XYZ \ Mary Poppins \ myOtherFile.txt

我对批处理脚本知之甚少,并且不了解PowerShell。通过修改我在StackOverflow上找到的脚本,我设法搞砸了(幸运的是,它是一个测试目录)。 [我在这里播放的剧本可以在这里找到: PowerShell Script to move folders one level up and delete the previous containing folder]

如果有人能帮我解决这个问题会很棒。我真的很感激。

感谢。

2 个答案:

答案 0 :(得分:0)

这应该这样做:

@echo off
setlocal enabledelayedexpansion

cd /d D:\XYZ
for /f "tokens=*" %%a in ('dir /b /ad') do (
  if exist "%%a\%%a" (
    xcopy /E "%%a\%%a\*" "%%a"
    rd /s /q "%%a\%%a" 
  )
)

答案 1 :(得分:0)

我会去PowerShell路线。这有两个选项,默认情况下会删除任何双重文件夹,所以...
Z:\ XYZ \ John Doe \ John Doe \ My Documents \ Stuff \ Stuff \ ItsAFile.txt
变为:
Z:\ XYZ \ John Doe \ My Documents \ Stuff \ ItsAFile.txt
如果你只想摆脱第6行的第一个重复文件夹注释,并取消注释第7行。如果您不喜欢报告部分,请删除/注释掉写入输出行。

$BasePath = "D:\XYZ"
gci $BasePath -recurse | %{
    $OriginalFile = $_
    If($OriginalFile.PSIsContainer){$FilePath = $_.FullName.ToString().Split('\')}
    Else{$FilePath = $_.Directory.ToString().Split('\')}
    for($i=1;$i -lt $FilePath.Count;$i++){    #Comment out this line to change to Base Path +2 folders method
#    for($i=0;$i -lt $($BasePath.Split('\').Count +2);$i++){    #Uncomment to only affect the first 2 folders past the base path
        if($filepath[$i] -and ($FilePath[$i] -ieq $FilePath[$i-1])){
            $FilePath[$i-1] = $Null
        }
    }
    ($FilePath|?{$_}) -join '\'|%{
        if($OriginalFile.PSIsContainer){
            If(!($OriginalFile.FullName -ieq $_)){
            Write-Output "Moving folder $($OriginalFile.fullname) to $_"
            move-item "$($OriginalFile.fullname)\*" $_ -ErrorAction SilentlyContinue
            Remove-Item $OriginalFile.fullname -ErrorAction SilentlyContinue}
        }else{
            If(!($OriginalFile.Directory.ToString() -ieq $_)){
            Write-Output "Moving file $($OriginalFile.fullname) to $(Resolve-Path "$_\..")"
            move-item $OriginalFile.fullname "$_\.." -ErrorAction SilentlyContinue
        }}
    }
}

要逐步完成,它:

  1. 拉出基本路径中每个文件夹或文件的目录列表。

  2. 对于每一个,它会根据反斜杠字符拆分路径, 排除文件名。

  3. 然后逐步浏览每个文件夹,将每个文件夹与一个文件夹进行比较 在路径之前(或者如果你只是步骤前几个段) 走那条路)。

  4. 如果两个顺序文件夹匹配,则删除第一个文件夹。

  5. 然后在该过程结束时重建路径。

  6. 之后将修改后的路径与原始路径进行比较,如果是 它们是不同的,它将该项目移动到修改后的路径。

  7. 它以不同的方式处理文件和文件夹,因为它使用文件夹的.FullName属性和文件的.Directory属性。