I am really trying to figure this out, so bear with me, and thanks in advance for any assistance. I'm still struggling with understanding proper use of FOR /F "Delims" and "Tokens".

EDIT: Ultimately what I need/want to do is any line containing the flag *EXTRA File or Newer in the log file, to extract the file path and file name and use ROBOCOPY to copy those files to another drive, with copied files to go under a date and time stamped folder.

I have a robocopy log file output that looks something like this:

   ROBOCOPY     ::     Robust File Copy for Windows                              

  Started : Friday, March 27, 2020 6:04:32 AM
   Source : P:\PC_BACKUP\
     Dest : X:\PC_BACKUP\

    Files : *.*

  Options : *.* /TS /FP /TEE /S /E /DCOPY:DA /COPY:DAT /PURGE /MIR /NP /MT:1 /R:2 /W:10 


      *EXTRA File         11.2 g 2020/03/25 06:09:27    X:\PC_BACKUP\DellAndrew\75E4FF97EDCDE7C0-09-09.mrimg
      *EXTRA File         29.7 g 2020/03/26 07:33:31    X:\PC_BACKUP\DellJordan\DC0297C23493575B-10-10.mrimg
      *EXTRA File         27.8 g 2020/03/26 05:10:12    X:\PC_BACKUP\P650HSG\677CFE5FA9EB27B1-10-10.mrimg
        Newer             15.2 g 2020/03/27 06:36:52    P:\PC_BACKUP\DellAndrew\75E4FF97EDCDE7C0-10-10.mrimg
        New File           2.2 g 2020/03/27 06:41:31    P:\PC_BACKUP\DellAndrew\75E4FF97EDCDE7C0-19-19.mrimg
        Newer             31.1 g 2020/03/27 07:36:04    P:\PC_BACKUP\DellJordan\DC0297C23493575B-11-11.mrimg
        New File           4.4 g 2020/03/27 07:44:55    P:\PC_BACKUP\DellJordan\DC0297C23493575B-23-23.mrimg
        Newer             27.8 g 2020/03/27 05:07:37    P:\PC_BACKUP\P650HSG\677CFE5FA9EB27B1-11-11.mrimg
        New File           1.8 g 2020/03/27 05:09:25    P:\PC_BACKUP\P650HSG\677CFE5FA9EB27B1-22-22.mrimg


               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :         6         6         6         0         0         0
   Files :        74         6        68         0         0         3
   Bytes :   2.266 t  82.830 g   2.185 t         0         0  68.862 g
   Times :   0:16:49   0:04:12                       0:00:00   0:04:12

   Speed :           352546983 Bytes/sec.
   Speed :           20172.900 MegaBytes/min.
   Ended : Friday, March 27, 2020 6:12:56 AM

I have managed to be able to trim this file down to just the path and file name for files I want to work with ("Newer" and "*EXTRA File" paths) exported to a log using:

set logname=%~1
findstr /L /G:extractnewer.txt %logname%.log > extract.log
findstr /L /G:extractextrafile.txt %logname%.log >> extract.log

setlocal DisableDelayedExpansion
for /f "tokens=1* delims=\" %%A in (extract.log) do echo %%B >> trim.log

There's probably a better way to do this, but it works for me so far. So trim.log output from that looks like this:


Ultimately I need the file path and file name separated so I can use them to do a robocopy file copy. For example it will go through each line in the trim.log:


so I can do a:

robocopy X:\%filepath% T:\%datefolder%\%filepath%\ %filename%

But I am struggling to get the proper FOR /F to extract the path and file separately.

Thanks for any assistance.

  • 2
    Nice effort and showing everything you're doing here. Nice detail!! Mar 27 '20 at 18:59
  • 2
    Try something like For /f "delims=\ tokens=1-5" %A IN (trim.log) DO ECHO %A %B %C and play with that. You can then set %A as a variab;e, set %B as a variable and set %C as a variable and use those in an iteration to do what you need splitting the values accordingly in other commands placing where needed to build the strings you need fort he final output. Double you %% signed accordingly if using batch and not commands though obviously. Mar 27 '20 at 19:15
  • 1
    Thanks for the pointers. I'll fumble along with it a bit more and see if I can figure out how to make it work. Most of this is just researching and trial and error to end up at where I'm at.
    – HTWingNut
    Mar 27 '20 at 19:39
  • Path is %%~pB, Filename is %%~nxB. See Parameters / Arguments - Windows CMD - SS64.com
    – DavidPostill
    Mar 27 '20 at 20:47

Since you already have the file path parts needed in the trim.log file, you can use it for both the scripted solutions below and test to confirm either will work for your need.

1. Batch Script

For /f "delims=\ tokens=1-5" %%A IN (trim.log) DO (
    robocopy X:\%%~A\%%~B T:\%datefolder%\%%~A\%%~B\ %%~C

2. Batch Script

Note: The Setlocal EnableDelayedExpansion helps to handle the expanding of the variables set in the loop accordingly to be properly used and not parsed at runtime.

Setlocal EnableDelayedExpansion
For /f "delims=\ tokens=1-5" %%A IN (trim.log) DO (
    SET "filepath=%%~A\%%~B"
    SET "filename=%%~C"
    robocopy X:\!filepath! T:\%datefolder%\!filepath!\ !filename!

3. Batch w/ PowerShell Helper

I gave up trying to get that to work with batch and just added a simple PowerShell helper to help concatenate the file path and file name parts accordingly for the Robocopy argument values.

This is still executed as a batch file, you'll just want to ensure the full path and file name to the trim.log is set in its variable, and the datefolder variable value is set before the logic beneath both of those run so fit into your existing script accordingly to ensure proper order.

SET "tFile=C:\Folder\Path\trim.log"
SET "datefolder=20200328"

SET PSScript=%temp%\PS~TrimTemp.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"

ECHO Get-Content "%tFile%" ^| %%{                                       > "%PSScript%"
ECHO     $path  = (Split-Path "\$_" -Parent);                           >> "%PSScript%"
ECHO     $path  = (($path.split("\")[1..999]) -join "\");               >> "%PSScript%"
ECHO     $fname = ($_.Split("\")[-1]).Trim();                           >> "%PSScript%"
ECHO     If($path){Robocopy "X:\$path" "T:\%datefolder%\$path" $fname } >> "%PSScript%"
ECHO     };                                                             >> "%PSScript%"

SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"

Further Resources

  • And for the batch experts in case any read this, I was having trouble with SET "Var=!filepath:!filename!=!" and getting it to parse out the value of the !filename! variable within the loop. Tried all sorts of variations with ! and % both and delayed expansion enabled, etc. I thought I had done that in the past, but after a few tries, I switched to an easier solution. I've been in remote IT server VM building mode all day though so about drained anyway!! I also tried with David's suggestion with %%~p and %%~nx but %%~p appended the file path in set and tried usebackq, etc. too Mar 28 '20 at 0:47
  • Thanks, but still same result. No data copied. The output stills hows as before i.e. Robocopy X:\$path instead of the actual path.
    – HTWingNut
    Mar 28 '20 at 20:58
  • OK, well this time it generated the folder structure but didn't copy the files. It's odd. For test, I removed all files except one from trim.log and ran your script, and then also did a robocopy manually for comparison. For some reason it doesn't copy the files with your script even though the robocopy command executes. Here's output from your script: pastebin.com/fv3u3xwv and here's output running same robocopy direct from command line: pastebin.com/12acUdnX I don't understand why it's not copying files the same as it does running direct robocopy from command line.
    – HTWingNut
    Mar 29 '20 at 0:05
  • Pastebin of %temp%\PS~TrimTemp.ps1: pastebin.com/nyP5zsbE
    – HTWingNut
    Mar 29 '20 at 0:43
  • Same result. Output from batch file: pastebin.com/W3kLh1MN and PS~TrimTemp.ps1: pastebin.com/cXfHKr1Z
    – HTWingNut
    Mar 29 '20 at 1:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.