Merge Selected Files (Batch)
Moderators: Hacker, petermad, Stefan2, white
I'm running Win7 x64 Pro.
Changing the statement as proposed does render following error: "- was unexpected at this time."
Regards, EricB
Edit:
using %AddFileHeader%-- EQU -- (and also in 3 other instances with NEQ) seems to work. Apparently characters directly preceding a variable is not accepted by the processor.
Edit2:
but when I use /H=*** when calling the batchfile it again does not work. Message: -- was unexpected this time.
Changing the statement as proposed does render following error: "- was unexpected at this time."
Regards, EricB
Edit:
using %AddFileHeader%-- EQU -- (and also in 3 other instances with NEQ) seems to work. Apparently characters directly preceding a variable is not accepted by the processor.
Edit2:
but when I use /H=*** when calling the batchfile it again does not work. Message: -- was unexpected this time.
- Balderstrom
- Power Member
- Posts: 2148
- Joined: 2005-10-11, 10:10 UTC
Heres a slightly changed, added a Goto:EOF into :_LOOP_FileList
which may of been triggering an erroneous/false error message.
If you could try this, and tell me what your
1) Button| Command, Parameters
2) Source path, source filenames.
which may of been triggering an erroneous/false error message.
If you could try this, and tell me what your
1) Button| Command, Parameters
2) Source path, source filenames.
Code: Select all
SET GetFileName=0
::
:: IF GetFileName is 1 - You will Prompted for the Final MergedFileName.
:: If you Input an existing filename, Prompt Permission to Overwrite it.
:: IF Overwrite is allowed, Also prompt to delete existing Source Files.
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SET UnderScore=_
SET MoveSource=""
SET QueryDelete=0
SET DeleteSource=0
SET ForcedOverWrite=0
SET OutFile=""
SET OutOldF=""
SET AddFileHeader=
SET FileList=
SET FileList_Count=0
:_READARGS
SET NextArg="%~1"
IF %NextArg%=="/D" SET DeleteSource=1&SHIFT&GOTO:_READARGS
IF %NextArg%=="/F" SET ForcedOverWrite=1&SHIFT&GOTO:_READARGS
IF "%NextArg:~1,2%"=="/M" CALL:_SETFILE MoveSource "%~2" &SHIFT&SHIFT&GOTO:_READARGS
IF "%NextArg:~1,2%"=="/O" CALL:_SETFILE OutFile "%~2" &SHIFT&SHIFT&GOTO:_READARGS
IF "%NextArg:~1,2%"=="/H" CALL:_SETSAFESTRING AddFileHeader %~2 &SHIFT&SHIFT&GOTO:_READARGS
IF %NextArg% == "%~1" CALL:_ADD_FileList "%~1"&SHIFT
IF "%~1" NEQ "" GOTO:_READARGS
FOR /D %%D IN (%FileList%) DO CALL:_VERIFYFILES %%D
IF %FileList_Count% LSS 2 CALL:_ERRORMSG "Select at least 2 files to Merge."
IF %OutFile%=="/O" SET OutFile="%~1"&SET ForcedOverWrite=1
:_RENAME_MASTER
SET Master="%~n1%UnderScore%_MERGED%~x1"
IF EXIST %Master% SET UnderScore=_%UnderScore%& GOTO:_RENAME_MASTER
IF -%AddFileHeader%- EQU -- GOTO:_LOOP_FileList
:_CreateTempHeadersFolder
MKDIR "%UnderScore%MergeFilesTempHeaders%UnderScore%" 1>NUL 2>&1
IF %ERRORLEVEL% NEQ 0 SET UnderScore=_%UnderScore%& GOTO:_CreateTempHeadersFolder
:_LOOP_FileList
CALL:_LOOP %FileList%
GOTO:EOF
:_LOOP
IF -%AddFileHeader%- NEQ -- CALL:_CREATE_HeaderFiles "%~1" %AddFileHeader% %UnderScore%MergeFilesTempHeaders%UnderScore%
IF -%AddFileHeader%- NEQ -- (
SET CopySTR=%CopySTR% + %HeaderFileName% + "%~1"
) ELSE (
SET CopySTR=%CopySTR% + "%~1"
)
SET DelMoveSTR=%DelMoveSTR% "%~1"
SHIFT
IF NOT "%~1"=="" GOTO:_LOOP
:_COPY
COPY /Y %CopySTR:~3% %Master% 1>NUL 2>&1
IF NOT EXIST %Master% CALL:_ERRORMSG "Merge Failed!"
ECHO. >> %Master%
IF %GetFileName%==0 GOTO:_MOVE_DELETE_FILES
FOR /L %%L IN (1,1,11) DO ECHO.
:_GET_FILENAME
IF %OutFile%=="" CALL:_GETINPUT
IF %OutFile%=="" (
IF NOT %OutOldF%=="" SET OutFile=%OutOldF%
SET QueryDelete=1
GOTO:_MOVE_DELETE_FILES
)
IF NOT EXIST %OutFile% GOTO:_MOVE_DELETE_FILES
IF %ForcedOverWrite%==1 GOTO:_MOVE_DELETE_FILES
ECHO.&ECHO.
ECHO %OutFile% Already Exists!
ECHO.&ECHO.
SET PromptExtra=[Press Enter to Overwrite %OutFile%]
SET OutOldF=%OutFile%
SET OutFile=""
GOTO:_GET_FILENAME
:_MOVE_DELETE_FILES
IF NOT %MoveSource%=="" (
MKDIR %MoveSource% 1>NUL 2>&1
FOR /D %%F IN (%DelMoveSTR%) DO MOVE %%F %MoveSource% 1>NUL 2>&1
MOVE /Y %Master% %OutFile% 1>NUL 2>&1
GOTO:EOF
)
IF %QueryDelete%==1 IF %DeleteSource%==0 (
SET /P QueryDelete=Delete Source Files ^(Y/N^)?
)
ECHO %QueryDelete%|FIND /I "Y" 1>NUL 2>&1 && SET DeleteSource=1
IF %DeleteSource%==1 DEL %DelMoveSTR% 1>NUL 2>&1
MOVE /Y %Master% %OutFile% 1>NUL 2>&1
IF -%AddFileHeader%- NEQ -- RMDIR /S /Q "%UnderScore%MergeFilesTempHeaders%UnderScore%" 1>NUL 2>&1
GOTO:EOF
:_ERRORMSG
CLS&ECHO.&ECHO.&ECHO.&ECHO [ERROR]: %~1&ECHO.&ECHO.
PAUSE&EXIT
GOTO:EOF
:_ADD_FileList
IF "%~1" NEQ "" SET FileList=%FileList% "%~1"&SET /A FileList_Count=%FileList_Count% + 1
GOTO:EOF
:_VERIFYFILES
SET isDir=%~a1
IF "%isDir%"=="" GOTO:EOF
IF "%isDir:~0,1%"=="d" CALL:_ERRORMSG "Select Files Only!"
GOTO:EOF
:_SETFILE
SET %1="%~2"
GOTO:EOF
:_CREATE_HeaderFiles
SET HeaderFileName=".\%~3\%~1.tmp"
ECHO.>>%HeaderFileName%
ECHO %~2 '%~1' %~2 >> %HeaderFileName%
GOTO:EOF
:_SETSAFESTRING
SET %1=%~2
GOTO:EOF
:_GETINPUT
IF NOT "%PromptExtra%"=="" ECHO %PromptExtra%
SET /P OutFile=Output File for Merged files?
IF NOT ^%OutFile:~0,1%==^" SET OutFile="%OutFile%
IF NOT ^%OutFile:~-1%==^" SET OutFile=%OutFile%"
GOTO:EOF
*BLINK* TC9 Added WM_COPYDATA and WM_USER queries for scripting.
I ran this in a folder d:\tools in a cmd window as "mergefiles file1.txt file2.txt" (which should work OK, isn't it?).
Last output line is d:\Tools>IF EXIST "_ _MERGED" SET UnderScore=__ & GOTO:_RENAME_MASTER
- was unexpected at this time.
The merged text file is now not created and two temp folders _ MergeFilesTempHeaders_ and __ MergeFilesTempHeaders__ (including nasty spaces in their name) now remain.
Regards, EricB
Last output line is d:\Tools>IF EXIST "_ _MERGED" SET UnderScore=__ & GOTO:_RENAME_MASTER
- was unexpected at this time.
The merged text file is now not created and two temp folders _ MergeFilesTempHeaders_ and __ MergeFilesTempHeaders__ (including nasty spaces in their name) now remain.
Regards, EricB
- Balderstrom
- Power Member
- Posts: 2148
- Joined: 2005-10-11, 10:10 UTC
Odd, is it possible your file has a blank space after the underscore in this ?
"SET UnderScore=_ "
There definitely shouldn't be spaces in those Folders, and there definitely shouldn't be a space in between the underscores in
IF EXIST "_ _MERGED" ---> IF EXIST "__MERGED"
"SET UnderScore=_ "
There definitely shouldn't be spaces in those Folders, and there definitely shouldn't be a space in between the underscores in
IF EXIST "_ _MERGED" ---> IF EXIST "__MERGED"
*BLINK* TC9 Added WM_COPYDATA and WM_USER queries for scripting.
Indeed, file had extra blank for underscore variable. I copied/pasted your code and because of this every EOL marker was preceded by a space...
After correction of this everything works as expected. Running with only two files as argument does a correct merge and using /H=*** now indeed inserts a correct separator.
Well done!
Regards, EricB
After correction of this everything works as expected. Running with only two files as argument does a correct merge and using /H=*** now indeed inserts a correct separator.
Well done!
Regards, EricB
Follow-up:
If I define the button as follows
TOTALCMD#BAR#DATA
cmd.exe /C %COMMANDER_DRIVE%\Tools\mergeFiles.cmd /H=---
%S
%COMMANDER_PATH%\wciconex.dll,77
Merge Selected Files
-1
The merge runs correctly, but the resulting filename obtains name __merged instead of assuming part of the filename of the first file in the selection.
Regards, EricB
If I define the button as follows
TOTALCMD#BAR#DATA
cmd.exe /C %COMMANDER_DRIVE%\Tools\mergeFiles.cmd /H=---
%S
%COMMANDER_PATH%\wciconex.dll,77
Merge Selected Files
-1
The merge runs correctly, but the resulting filename obtains name __merged instead of assuming part of the filename of the first file in the selection.
Regards, EricB
- Balderstrom
- Power Member
- Posts: 2148
- Joined: 2005-10-11, 10:10 UTC
Yeah, to assume the first filename as the output we would need to do:
cmd.exe /k mergeFiles.cmd /O="%1"
If you want a separator between the merged files:
cmd.exe /k mergeFiles.cmd /O="%1" /H=---
OR:
cmd.exe /k mergeFiles.cmd /O="%1" /H=***
I'm just not running into any errors on my end, in either folders with no directories (the major glitch after adding /H), nor folders with just files-to-be-merged.
Now if you do use /O="%1" - that will overwrite the first input file (at the end). You might want to also either use /D (force delete source) or
mergeFiles /O="%1" /F /H=--- /M=".\BAK"
: 1st-File-AsName, ForceOverwrite First-File if it exists, Separator, and backup sourceFiles (before overwrite) to .\BAK folder.
cmd.exe /k mergeFiles.cmd /O="%1"
If you want a separator between the merged files:
cmd.exe /k mergeFiles.cmd /O="%1" /H=---
OR:
cmd.exe /k mergeFiles.cmd /O="%1" /H=***
I'm just not running into any errors on my end, in either folders with no directories (the major glitch after adding /H), nor folders with just files-to-be-merged.
Now if you do use /O="%1" - that will overwrite the first input file (at the end). You might want to also either use /D (force delete source) or
mergeFiles /O="%1" /F /H=--- /M=".\BAK"
: 1st-File-AsName, ForceOverwrite First-File if it exists, Separator, and backup sourceFiles (before overwrite) to .\BAK folder.
*BLINK* TC9 Added WM_COPYDATA and WM_USER queries for scripting.
- Balderstrom
- Power Member
- Posts: 2148
- Joined: 2005-10-11, 10:10 UTC
Can you test this version, I completely forgot that the old version did the FirstFile__MERGED.EXT - which got munged when I moved the code to create a FileList for the /H param 
The default output (outfile) should be as it was.
:: Moved ADD_FileList, Rename_Master, and OutFile check/fix into the VerifyFiles routine, which has access to the required %1 parameter.

The default output (outfile) should be as it was.
:: Moved ADD_FileList, Rename_Master, and OutFile check/fix into the VerifyFiles routine, which has access to the required %1 parameter.
Code: Select all
SET GetFileName=0
SET UnderScore=_
SET MoveSource=""
SET QueryDelete=0
SET DeleteSource=0
SET ForcedOverWrite=0
SET OutFile=""
SET OutOldF=""
SET AddFileHeader=
SET FileList=
SET FileList_Count=0
:_READARGS
SET NextArg="%~1"
IF %NextArg%=="/D" SET DeleteSource=1&SHIFT&GOTO:_READARGS
IF %NextArg%=="/F" SET ForcedOverWrite=1&SHIFT&GOTO:_READARGS
IF "%NextArg:~1,2%"=="/M" CALL:_SETFILE MoveSource "%~2" &SHIFT&SHIFT&GOTO:_READARGS
IF "%NextArg:~1,2%"=="/O" CALL:_SETFILE OutFile "%~2" &SHIFT&SHIFT&GOTO:_READARGS
IF "%NextArg:~1,2%"=="/H" CALL:_SETSAFESTRING AddFileHeader %~2 &SHIFT&SHIFT&GOTO:_READARGS
IF %NextArg% == "%~1" CALL::_VERIFYFILES "%~1"&SHIFT
IF "%~1" NEQ "" GOTO:_READARGS
IF %FileList_Count% LSS 2 CALL:_ERRORMSG "Select at least 2 files to Merge."
IF -%AddFileHeader%- NEQ -- CALL:_CreateTempHeadersFolder
CALL:_LOOP %FileList%
GOTO:EOF
:_LOOP
IF -%AddFileHeader%- NEQ -- CALL:_CREATE_HeaderFiles "%~1" %AddFileHeader%
IF -%AddFileHeader%- NEQ -- (
SET CopySTR=%CopySTR% + %HeaderFileName% + "%~1"
) ELSE (
SET CopySTR=%CopySTR% + "%~1"
)
SET DelMoveSTR=%DelMoveSTR% "%~1"
SHIFT
IF NOT "%~1"=="" GOTO:_LOOP
:_COPY
COPY /Y %CopySTR:~3% %Master% 1>NUL 2>&1
IF NOT EXIST %Master% CALL:_ERRORMSG "Merge Failed!"
ECHO. >> %Master%
IF %GetFileName%==0 GOTO:_MOVE_DELETE_FILES
FOR /L %%L IN (1,1,11) DO ECHO.
:_GET_FILENAME
IF %OutFile%=="" CALL:_GETINPUT
IF %OutFile%=="" (
IF NOT %OutOldF%=="" SET OutFile=%OutOldF%
SET QueryDelete=1
GOTO:_MOVE_DELETE_FILES
)
IF NOT EXIST %OutFile% GOTO:_MOVE_DELETE_FILES
IF %ForcedOverWrite%==1 GOTO:_MOVE_DELETE_FILES
ECHO.&ECHO.
ECHO %OutFile% Already Exists!
ECHO.&ECHO.
SET PromptExtra=[Press Enter to Overwrite %OutFile%]
SET OutOldF=%OutFile%
SET OutFile=""
GOTO:_GET_FILENAME
:_MOVE_DELETE_FILES
IF NOT %MoveSource%=="" (
MKDIR %MoveSource% 1>NUL 2>&1
FOR /D %%F IN (%DelMoveSTR%) DO MOVE %%F %MoveSource% 1>NUL 2>&1
MOVE /Y %Master% %OutFile% 1>NUL 2>&1
GOTO:EOF
)
IF %QueryDelete%==1 IF %DeleteSource%==0 (
SET /P QueryDelete=Delete Source Files ^(Y/N^)?
)
ECHO %QueryDelete%|FIND /I "Y" 1>NUL 2>&1 && SET DeleteSource=1
IF %DeleteSource%==1 DEL %DelMoveSTR% 1>NUL 2>&1
MOVE /Y %Master% %OutFile% 1>NUL 2>&1
IF -%AddFileHeader%- NEQ -- RMDIR /S /Q "%UnderScore%MergeFilesTempHeaders%UnderScore%" 1>NUL 2>&1
GOTO:EOF
:_ERRORMSG
CLS&ECHO.&ECHO.&ECHO.&ECHO [ERROR]: %~1&ECHO.&ECHO.
PAUSE&EXIT
GOTO:EOF
:_VERIFYFILES
SET isDir=%~a1
IF "%isDir%"=="" GOTO:EOF
IF "%isDir:~0,1%"=="d" CALL:_ERRORMSG "Select Files Only!"
IF "%~1" NEQ "" SET FileList=%FileList% "%~1"&SET /A FileList_Count=%FileList_Count% + 1
IF %FileList_Count% GTR 1 GOTO:EOF
:_RENAME_MASTER
SET Master="%~n1%UnderScore%_MERGED%~x1"
IF EXIST %Master% SET UnderScore=_%UnderScore%& GOTO:_RENAME_MASTER
:_FIX_OUTFILE
IF %OutFile%=="/O" SET OutFile="%~1"&SET ForcedOverWrite=1
GOTO:EOF
:_SETFILE
SET %1="%~2"
GOTO:EOF
:_CreateTempHeadersFolder
SET HeaderFolderName=%UnderScore%MergeFilesTempHeaders%UnderScore%
MKDIR %HeaderFolderName% 1>NUL 2>&1
IF %ERRORLEVEL% NEQ 0 SET UnderScore=_%UnderScore%& GOTO:_CreateTempHeadersFolder
GOTO:EOF
:_CREATE_HeaderFiles
SET HeaderFileName=".\%HeaderFolderName%\%~1.tmp"
ECHO.>>%HeaderFileName%
ECHO %~2 '%~1' %~2 >> %HeaderFileName%
GOTO:EOF
:_SETSAFESTRING
SET %1=%~2
GOTO:EOF
:_GETINPUT
IF NOT "%PromptExtra%"=="" ECHO %PromptExtra%
SET /P OutFile=Output File for Merged files?
IF NOT ^%OutFile:~0,1%==^" SET OutFile="%OutFile%
IF NOT ^%OutFile:~-1%==^" SET OutFile=%OutFile%"
GOTO:EOF
Yes, this version indeed creates the FirstFile__merged.ext again, either when run from CMD window or as a button command.
Also tested the /H parameter for both situations which still works as expected.
When FirstFile__merged.ext already exists, the new result obtains an extra underscore in its name, nice one!
Seems that this version can be de-ECHO-ed and published.
One suggestion which may be (or may not be) of value:
the batch file is now setting all kinds of env vars. When running it more times from the same CMD window this will cause some trouble. How about cleaning up / resetting the env vars at the end? This way the batch could also be used stand alone, without TC.
Regards, EricB
Also tested the /H parameter for both situations which still works as expected.
When FirstFile__merged.ext already exists, the new result obtains an extra underscore in its name, nice one!
Seems that this version can be de-ECHO-ed and published.
One suggestion which may be (or may not be) of value:
the batch file is now setting all kinds of env vars. When running it more times from the same CMD window this will cause some trouble. How about cleaning up / resetting the env vars at the end? This way the batch could also be used stand alone, without TC.
Regards, EricB