Copy first level folder and consolidate all the fi

2020-01-19 11:02发布

I have multiple folders s1,s2.....sn on main directory. Each of these folders have multiple sub folders, folders within folders and then files. Structure kind of looks like:

mainDir

  -s1
       -f1
         -c1
           -a.txt
           -b.txt
         -c2
           -m.txt
           -n.txt
       -f2
         -c1
           -aaa.txt
           -bbb.txt
         -c2
           -mmm.txt
           -nnn.txt
     -s2
       -f1
         -c1
           -a.txt
           -b.txt
         -c2
           -m.txt
           -n.txt
       -f2
         -c1
           -aaa.txt
           -bbb.txt
         -c2
           -mmm.txt
           -nnn.txt
     -s3 ..................

Now we need to get rid of all subfolders and keep only . the first level folders and all the underlying files. So final destination should like:

DestDirectory
      -s1
        -a.txt
        -b.txt
        -m.txt
        -n.txt
        -aaa.txt
        -bbb.txt
        .....so on
      -s2
        -a.txt
        -b.txt
        -m.txt
        -n.txt
        -aaa.txt
        -bbb.txt
        .....so on

3条回答
贪生不怕死
2楼-- · 2020-01-19 11:48

The first thing you need to do is to find out if there would be any filename collisions occur when moving files from multiple directories into a single directory.

=== Find-DupeFilenames.ps1

$h = @{}

Get-ChildItem -File -Recurse |
    ForEach-Object {
        if ($h.ContainsKey($_.Name)) {
            "Name conflict {0} is in both {1} and {2}" -f @($_.Name, $h[$_.Name], $_.DirectoryName)
        } else {
            $h.Add($_.Name, $_.DirectoryName)
        }
    }

If you need to run this from a cmd.exe shell prompt, use this to get a quick count.

CD /D C:\mainDir
powershell -NoLogo -NoProfile -Command "(C:\src\Find-DupeFilenames.ps1 | Measure-Object).Count"

Use this to list all conflicted filenames.

CD /D C:\mainDir
powershell -NoLogo -NoProfile -Command ".\Find-DupeFilenames.bat"
查看更多
Explosion°爆炸
3楼-- · 2020-01-19 11:54

How is this any different from your Previous question? How to copy files from sub folder only using cmd?

Perhaps in your previous Q you had all same-named folders?

The Code below should also work for the differently named folders as you described here.

CMD Script:

@(SETLOCAL
  ECHO OFF
  SET "_MainDir=C:\Main\Dir"
  SET "_DestDir=%Temp%\Destination\Main\Dir"
)

FOR /D %%A in (
  %_MainDir%\*
) DO (
  IF NOT EXIST "%_DestDir%\%%~nxA" MD "%_DestDir%\%%~nxA"
  FOR /F %%a IN ('
    DIR /A-D /S /B "%%~fA\*"
  ') DO (
    ECHO Copying: "%%~fa"
    ECHO To: "%_DestDir%\%%~nxA\%%~nxa"
    COPY /B /V /Y "%%~fa" "%_DestDir%\%%~nxA\%%~nxa"
  )
)
查看更多
Fickle 薄情
4楼-- · 2020-01-19 11:55

I would use a for /D loop to iterate the first-level sub-directories, then a nested for /R loop to iterate through all files in the immediate sub-directories, then use copy to copy each file individually in order to achieve the flat destination directory hierarchy. To avoid file name collisions (meaning that files with the same name appear in different source sub-directory hierarchy levels), an if exist directive can be used. So here is the code:

rem // Loop through immediate sub-sirectories of main directory:
for /D %%I in ("D:\MainDir\*") do (
    rem // Temporarily change to the currently iterated sub-directory:
    pushd "%%~I" && (
        rem // Iterate through all files in the current directory recusrively:
        for /R %%J in ("*.*") do (
            rem /* Create destination directory if necessary, which is named like
            rem    the current directory, that is the first source sub-directory: */
            2> nul md "D:\CopyDir\%%~nxI"
            rem // Temporarily change to the destination directory:
            pushd "D:\CopyDir\%%~nxI" && (
                rem // Check for potential file name collisions:
                if not exist "%%~nxJ" (
                    rem // No collision, hence copy current file:
                    copy "%%~J" "%%~nxJ"
                ) else (
                    rem // Collision, so return an error message:
                    >&2 echo ERROR: "%%~nxI\%%~nxJ" already exists!
                )
                rem // Return from destination directory:
                popd
            )
        )
        rem // Return from currently iterated source sub-directory:
        popd
    )
)
查看更多
登录 后发表回答