Search code examples
batch-filecmdbatch-rename

How do I copy all files of a nested directory structure into one new directory with adding the recursive path to the file name?


maybe some could give me some help with my issue: students upload their java codes via MS Teams assignments that I want to review (and compare with each other) locally.

It is possible for me as a teacher to do a bulk download of all submissions. Extracting the zip reveals the following structure:

  • root
    • student1name
      • project1
        • version1
          • file1.java
          • maybe also other files like file1.class, myfirstcodepastedinword.doc, screenshotofcode.jpg...
        • version2 //optional
          • file1.java
          • subdir // optional
            • otherfile.class
            • nextsubdir
              • lastfile.txt ...
      • project2
        • version1 ...
    • student2name
      • project1
        • version1
          • nextClass.java .. and so on...

What I am looking for is a litte batch that collects all project-sepecific submissions together in one directory (for being able to do simple comparisons). For identification, the student's name and all leading subdirectories must be added to the new file name.

So, after calling "collectSubmissions.bat", the result should be a new dir called "Submissions" containing all files as follows:

  • project1
    • student1name-version1-file1.java
    • student1name-version1-file1.class (could by omitted, but too much effort, I will simply ignore this manually)
    • student1name-version1-myfirstcodeinword.doc
    • student1name-version1-screenshotofcode.jpg
    • student1name-version2-file1.java
    • student1name-version2-subdir-otherfile1.class
    • student1name-version2-subdir-nextsubdir-lastfile.txt
    • ...
    • student2name-version1-file1.java
    • ...
  • project2
    • student1name-version1-nextClass.java ....

I did some research and tried different approaches (starting How can I recursively copy files of a specific pattern into a single flat folder on Windows?) and found one pretty close to my needs here:

How do I copy files with adding folder name to destination file name?

But only the closest parent directory name is used here. But in my case, there can be multiple nested folders, so I am hoping that someone could give me some advice how to do that.

Thank you so much in advance for your help!


Solution

  • @ECHO Off
    SETLOCAL ENABLEDELAYEDEXPANSION
    rem The following settings for the source directory, destination directory, target directory,
    rem batch directory, filenames, output filename and temporary filename [if shown] are names
    rem that I use for testing and deliberately include names which include spaces to make sure
    rem that the process works using such names. These will need to be changed to suit your situation.
    
    SET "sourcedir=u:\your files"
    SET "destdir=u:\your results"
    
    SET "remove=%sourcedir:\=-%"
    
    FOR /f "delims=" %%b IN ('dir /b /s /a-d "%sourcedir%\*" ') DO (
     SET "fullname=%%b"
     FOR /f "tokens=1,2*delims=\" %%u IN ("!fullname:%sourcedir%\=!") DO (
      MD "%destdir%\%%v" 2>NUL
      SET "newname=%%u-%%w"
      SET "newname=!newname:\=-!"
      COPY "%%b" "%destdir%\%%v\!newname!" >nul
     )
    )
    
    GOTO :EOF
    

    As to the practicalities (assuming this is intended as an exercise in plagiarism-detection)

    A student could make the detection difficult by

    • Changing the whitespace in the file
    • Changing variable/method names
    • Changing the sequence in which methods are defined in the file
    • Changing the sequence of statements (eg X,Y,Z becomes Z,Y,X where those statements are not interdependent)
    • Changing the sequence of terms in statements (eg x+3 and 3+x are not identical but produce identical results)

    ...and others