Reverse results of Tree command to create directories/files

Reverse results of Tree command to create directories/files

7
NewbieNewbie
7

    Apr 04, 2016#1

    I have been given a file that is an output of a Windows tree command - tree /a /f. Below is just a sample of what the output looks like. So, my question is:

    Has anyone written a script or macro to recreate the directory structure and files from this output?

    I am not that adapt with UE so I hate to reinvent the wheel if someone has already done this. I was just going to use the (mkdir) command to create the directory and all subdirectories, and then the command "fsutil file createnew whateverfilename.txt 0" to create an empty file with 0 bytes.

    Where you see the +--- that denotes it is a directory in the root of wherever you did the tree command, and the | | denotes the files under that directory. Then where you see | +--- that shows it is a subdirectory underneath the directory above it, and so on and so forth.

    So has anyone something already written that I could use?

    Code: Select all

    +---Mirth3.x
    |   |   MConn_v3_0_1_UserGuide.pdf
    |   |   mirthconnect.zip
    |   |   Unofficial Mirth Connect Developer's Guide.pdf
    |   |   
    |   +---BackUps
    |   |       2014-06-11 Mirth Backup.xml
    |   |       attachment.xml
    |   |       PrimeSUITE to CaptureRx.xml
    |   |       Sample Channel.xml
    |   |       Sender Channel.xml
    |   |       SOMC - 2014-06-12 Mirth Backup.xml
    |   |       v2 - v3 Transformation Channel.xml
    |   |       
    |   +---Eligibility.6931.ACK-NACK
    |   |   +---Channels
    |   |   |       Code Templates.xml
    |   |   |       Global Script.xml
    |   |   |       HL7v2 Ack Channel.xml
    |   |   |       HL7v3 Ack Channel.xml
    |   |   |       HL7v3 Verification Channel.xml
    |   |   |       Logging Channel.xml
    |   |   |       Sender Channel.xml
    |   |   |       v2-v3 Tranformation Channel.xml
    |   |   |       
    |   |   +---custom-lib
    |   |   |   |   jsr305-2.0.1.jar
    |   |   |   |   phloc-commons-4.0.7.jar
    |   |   |   |   phloc-schematron-2.6.2.jar
    |   |   |   |   postgresql-9.2-1003.jdbc4.jar
    |   |   |   |   saxon9-dom.jar
    |   |   |   |   slf4j-api-1.7.5.jar
    |   |   |   |   
    |   |   |   +---coreschemas
    |   |   |   |       datatypes-rX-cs.xsd
    |   |   |   |       infrastructureRoot-r2.xsd
    |   |   |   |       iso-21090_hl7-r2_datatypes.xsd
    |   |   |   |       NarrativeBlock.xsd
    |   |   |   |       voc-r2.xsd
    |   |   |   |       
    |   |   |   +---schema
    |   |   |   |       COCT_MT030203UV07.xsd
    |   |   |   |       COCT_MT040203UV09.xsd
    |   |   |   |       COCT_MT070000UV01.xsd
    |   |   |   |       COCT_MT090100UV01.xsd
    |   |   |   |       COCT_MT090108UV.xsd
    |   |   |   |       COCT_MT090300UV01.xsd
    |   |   |   |       COCT_MT090303UV01.xsd
    |   |   |   |       COCT_MT150000UV02.xsd
    |   |   |   |       COCT_MT150003UV03.xsd
    |   |   |   |       COCT_MT150007UV.xsd
    |   |   |   |       COCT_MT710000UV07.xsd
    |   |   |   |       COCT_MT960000UV05.xsd
    |   |   |   |       MCAI_MT900001UV01.xsd
    |   |   |   |       MCCI_MT000100UV01.xsd
    |   |   |   |       MCCI_MT000300UV01.xsd
    |   |   |   |       QUCR_IN200101UV01.xsd
    |   |   |   |       QUCR_IN210101UV01.xsd
    |   |   |   |       QUCR_MT200101UV01.xsd
    |   |   |   |       QUCR_MT210101UV01.xsd
    |   |   |   |       QUQI_MT020001UV01.xsd
    |   |   |   |       QUQI_MT120001UV01.xsd
    |   |   |   |       
    |   |   |   \---schematron
    |   |   |           QUCR_IN200101UV01.sch
    |   |   |           
    |   |   +---DB
    |   |   |       PostgreSQL-Eligibility DB.sql
    |   |   |       QBP_Log.accdb
    |   |   |       
    |   |   +---HL7v2
    

    6,681583
    Grand MasterGrand Master
    6,681583

      Apr 05, 2016#2

      First, is it possible for you to get the list of files in directory with full path, i.e. using

      dir "Path of root directory of directory tree\*" /A-D /B /S

      instead of tree /a /f which would make your task much easier to solve?

      See for details on Stack Overflow How to recursively list all files of desired file type in a specified directory?

      Second, which version of UltraEdit do you use and can a scripting solution be used instead of a macro solution?

      UltraEdit scripting engine supports variables, functions and nesting of loops which UltraEdit macros do not support. The usage of variables and recursive function calls would make this directory tree to file list conversion task much easier.
      Best regards from an UC/UE/UES for Windows user from Austria

      7
      NewbieNewbie
      7

        Apr 05, 2016#3

        Thank you for the reply, but unfortunately, no, I am unable to get anything other than this... The reason is that someone logged into one of my PC's at a different work location that was set to sync my Onedrive and they got it infected with ransomware. This in turn infected my Onedrive, which at that time I powered up a MacBook I had which had not synced for a couple of weeks and I pulled the dir list using tree since I assumed that was the best option at the time. Since I did not have it to keep a copy offline all I had was the directory structure and it has since been wiped out I believe.

        A script would be fine, I am just not sure the best way to do this but I had about 8,500+ files that I was able to recover but they now exist in a single directory and it would be a TON on manual labor to try and create the dir structure from scratch and then move these files into it.

        I am using the latest version of 23.00.0.59. Thanks!

        6,681583
        Grand MasterGrand Master
        6,681583

          Apr 06, 2016#4

          Okay, I think I understood the task now. You need to create from this tree output a batch file containing an xcopy command line for each file to recreate the directory structure and files. xcopy can create automatically a directory tree on copying a file, for example:

          Code: Select all

          xcopy "2014-06-11 Mirth Backup.xml" "C:\Temp\Mirth3.x\BackUps\" /C /G /H /I /K /Q /R /Y >nul
          It should be no problem for me to write the script which creates the batch file from tree output. But this takes some time and I don't know if get enough spare time for this development before next weekend.
          Best regards from an UC/UE/UES for Windows user from Austria

          7
          NewbieNewbie
          7

            Apr 06, 2016#5

            Mofi,

            That would be great! I can wait if you think you wouldn't mind doing it, I have actually never did anything with scripts within UE so I am not sure where to start. Would you need the file with the full directory and file listings, or is what I sent you enough? If it isn't just let me know the best way to send you that list and I will get it to you. Thanks!

            Neo

            6,681583
            Grand MasterGrand Master
            6,681583

              Apr 08, 2016#6

              I could very easily create my own tree list test files as all I needed to do is executing tree /F /A >TreeList.txt

              I found some time to develop the script which finally turned out to be quite simple.

              Code: Select all

              function ConvertNames (sDirectoryPath, nDirectoryLevel)
              {
                 while (g_nLineNumber < g_asLines.length)
                 {
                    var sLine = g_asLines[g_nLineNumber];
              
                    // Contains this line a directory name?
                    if (sLine.search(/^[| ]*[+\\]---/) >= 0)
                    {
                       // Get indent string having 4 characters per directory level.
                       var sLevel = sLine.replace(/^([| ]*).+$/,"$1");
              
                       // Return if the current directory level is too high.
                       if (nDirectoryLevel > (sLevel.length / 4)) return;
                       
                       // Replace the indent string by a backslash to get
                       // a backslash and the name of the next directory.
                       var sDirectoryName = sLine.replace(/^[| ]*[+\\]---/,"\\");
              
                       // Remove this line from the lines array.
                       g_asLines.splice(g_nLineNumber,1);
              
                       // Call this function once again with next directory path
                       // and next directory level.
                       ConvertNames(sDirectoryPath + sDirectoryName,nDirectoryLevel + 1);
                    }
                    
                    // Contains this line a file name?
                    else if (sLine.search(/^[| ]+[^| ]/) >= 0)
                    {
                       // Replace this line by directory path + file name.
                       // g_asLines[g_nLineNumber] = sDirectoryPath + sLine.replace(/^[| ]+/,"\\");
              
                       // Replace this line by the command line for the batch file:
                       // xcopy "file name" "directory path with backslash at end" /C /G /H /I /K /M /Q /R /Y >nul
                       g_asLines[g_nLineNumber] = sLine.replace(/^[| ]+(.+)$/,'%SystemRoot%\\System32\\xcopy.exe "$1" "' +
                                                                sDirectoryPath + '\\" /C /G /H /I /K /M /Q /R /Y >nul');
              
                       g_nLineNumber++;  // Process next line in array of lines.
                    }
              
                    // Remove lines which definitely do not contain a
                    // directory or a file name from the array of lines.
                    else
                    {
                       g_asLines.splice(g_nLineNumber,1);
                    }
                 }
              }
              
              if (UltraEdit.document.length > 0)  // Is any file opened?
              {
                 // Define environment for this script.
                 UltraEdit.insertMode();
                 if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
                 else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
              
                 // Determine line terminator type of active file.
                 if (UltraEdit.activeDocument.lineTerminator < 1) var sLineTerm = "\r\n";
                 else if (UltraEdit.activeDocument.lineTerminator == 1) var sLineTerm = "\n";
                 else var sLineTerm = "\r";
              
                 // Remove all trailing spaces in active file.
                 UltraEdit.activeDocument.trimTrailingSpaces();
                 
                 // Get all lines of active file into an array of lines.
                 UltraEdit.activeDocument.selectAll();
                 if (UltraEdit.activeDocument.isSel())
                 {
                    var g_asLines = UltraEdit.activeDocument.selection.split(sLineTerm);
                    UltraEdit.activeDocument.top();
                    var g_nLineNumber = 0;
              
                    // The root directory path can be any none empty string.
                    ConvertNames("C:\\Temp",0);
              
                    // Append an empty string to finally have last line also terminated.
                    g_asLines.push("");
              
                    // Write the converted list into a new ASCII DOS file.
                    UltraEdit.newFile();
                    UltraEdit.activeDocument.unixMacToDos();
                    UltraEdit.activeDocument.unicodeToASCII();
                    UltraEdit.activeDocument.write(g_asLines.join("\r\n"));
                    UltraEdit.activeDocument.top();
                 }
              }
              
              You have to edit the root path of target directory in the script which is currently "C:\\Temp". Please note that for each backslash in path you have to specify two backslashes.

              The script contains the lines:

              Code: Select all

                      // Replace this line by directory path + file name.
                       // g_asLines[g_nLineNumber] = sDirectoryPath + sLine.replace(/^[| ]+/,"\\");
              
                       // Replace this line by the command line for the batch file:
                       // xcopy "file name" "directory path with backslash at end" /C /G /H /I /K /M /Q /R /Y >nul
                       g_asLines[g_nLineNumber] = sLine.replace(/^[| ]+(.+)$/,'%SystemRoot%\\System32\\xcopy.exe "$1" "' +
                                                                sDirectoryPath + '\\" /C /G /H /I /K /M /Q /R /Y >nul');
              
              By uncommenting the second line and commenting instead the last two lines, the script would convert the tree list into a directory list as produced by dir "Root Path" /A-D /B /S which I used to verify if the conversion from tree list to a file name list really works.

              Note: Command tree ignores all files and directories having either system or hidden attribute set while the file list created by dir with /A-D includes also hidden and system directories and files.

              The script as is produces the lines for a batch file with xcopy command for each file name. I tested also this batch file with a large directory tree with more than 2000 files in more than 750 directories and it worked fine with no error.

              The batch file produced by the script should have at top the lines:

              Code: Select all

              @echo off
              cd /D "Source Path"
              attrib +a *
              
              Source Path must be the path of the directory containing the files to copy into the directory tree.

              I used /M parameter on each xcopy command line and explicitly set archive attribute on each file in source directory before starting the copy process in the batch file.

              I called the batch file from within a command prompt window to see possible errors output by xcopy, but there was no error. After batch processing finished, I could see which files where not copied by looking on the files still having archive attribute set. Those files were in a hidden or system directory or had the hidden or system attribute set and therefore were not in list created by tree. So batch copying from flat file list in source directory into recreated target directory tree worked perfect and the result was as expected.

              Note: The tree could have files with identical name in different directories. As the source directory can't have multiple files with identical name, it could happen that some xcopy commands fail because there is after first copying such a file and clearing archive attribute in source directory no more file with the same name with archive attribute still set.
              Best regards from an UC/UE/UES for Windows user from Austria

              7
              NewbieNewbie
              7

                Apr 10, 2016#7

                Hey Mofi,

                Thanks so much for your assistance! I appreciate you taking the time to work this out, it is much appreciated! Thanks again!