I have some pdf's in a folder that I need to organize them like this:
PDF name: 123.12.123.pdf ; 102030_01.pdf; 102030_02.pdf; 123.4512.34561.23412.pdf
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern: ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001.pdf
for this I have used the following code which works very well:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
I drag the pdfs into the .bat and it does the adjustment.
It happens that there is a case that I am not able to handle. Some pdfs need to be in the same folder, for example in the following case:
PDF name: 102030_01.pdf; 102030_02.pdf;
Note that the pdfs have the same number, only after the _ that we have the difference. In this case you would need to create a folder with the name:102030
And move the two files into it, modifying their name as follows:
102030_01.pdf -> P102030_V1_A0V0_T07-54-369-664_S00001.pdf
102030_02.pdf -> P102030_V1_A0V0_T07-54-369-664_S00002.pdf
Could anyone help?
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
if /i "%basename%" neq "%basename:_=%" goto sub2
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
:sub2
for /f "tokens=1*delims=_" %%b in ("%basename%") do (
MD "%~dp1%%b" 2>NUL
ECHO Move /Y %1 "%~dp1%%b\P%basename:-=%_V1_A0V0_T07-54-369-664_S000%%c_Volume%~x1"
)
Exit /B
Always test on dummy data first.
This code echoes the proposed move. After verification, remove the echo keyword to activate.
Caution: My reading of the code is that - should be removed from the basename in the new name, and that _Volume should be appended to the name part, which is not shown in your examples.
Essentially, if the basename contains _ then goto sub2.
sub2 partitions the name in basename, assigning the first part to %%b and the second to %%c (See for /? from the prompt for documentation)
Then the directory is created
The md will object if the directory already exists, hence the 2>nul in the original code (suppresses error messages)
If md found that error in the original then this appears to be a problem, so the move is not executed. In the new version, it is expected that the directory may already exist, so the errorlevel processing has been removed.
Related
I have some PDF files that I need to rename and move to specific folders to be able to import into a system.
The file by default has the following name:
ex: 12345.123456/1234-12.pdf
First I need to remove the characters "," "/" "-"
#echo off
setlocal EnabledelayedExpansion
for /r "C:\importation" %%a in (*) do (
set "newname=%%~na"
set "newname=!newname:.=!"
set "newname=!newname:-=!"
set "newname=!newname:/=!"
ren "%%~a" "!newname!%%~xa"
)
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern:
ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001_Volume.pdf
For that I drag the files to the following script:
#If Not "%~1" == "" For %%G In (%*) Do #MD "%%~dpG%%~nG" 2>NUL && Move /Y "%%~G" "%%~dpG%%~nG\P%%~nG_V1_A0V0_T07-54-369-664_S00001_Volume%%~xG"
I would like to do only one process, that is, join the two scripts and run only once.
Can someone help me?
Rather than dragging the files to the batch file I would like to run it and have it read the files (.pdf) from the folder
Is something like this what you are looking for?
The following will accept drag and drop of one or more files or directories, (subject to command line length restrictions). Each individually dropped PDF file and each PDF file within any dropped directory should be processed as requested.
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
Please note, as the character / is invalid in file or directory names, I have ignored that part of your question.
I created a .bat that will copy pdf file in specified server. The folder structure of file is like this :
\\server\
'----010000-0000\
'----010000-0000-0705-1\
'-------010000-0000-DATA.pdf
'----010000-0000-0705-2\
'-------010000-0000-DATA.pdf
010000-0000 is the code that the user will input. Then batch will search with the exact folder with the code as filename and must copy the pdf file..
My problem is the folder before the pdf file is always has a 4 random numbers which is 0705 (as an example). What I was thinking is to pass through that folder what ever the 4 random numbers value will be. To copy the pdf file
for example (if would do a static code, it will be like this) :
set /p code=Input Control Number:
goto FILE
:FILE
set VER=0
:FILE1
set /a VER +=1
if exist "%fp%\%CODE%\%CODE%-0705-%VER%\%CODE%-DATA.pdf" goto FPCOPY
IF NOT EXIST ELSE GOTO FILE1
:FPCOPY
xcopy "%fp%\%CODE%\%CODE%-0705-%VER%\%CODE%-DATA.pdf" "%HOMEPATH%\Desktop\Backup\%CODE%\" /D /E /C /I /Y /H
start "" "%HOMEPATH%\Desktop\Backup\%code%"
It will surely copy the data. But as I said that 4 digit numbers is always random.
What I have tried is this one (I only replace the 4 digit no. by an *) :
set /p code=Input Control Number:
goto FILE
:FILE
set VER=0
:FILE1
set /a VER +=1
if exist "%fp%\%CODE%\%CODE%-*-%VER%\%CODE%-DATA.pdf" goto FPCOPY
IF NOT EXIST ELSE GOTO FILE1
:FPCOPY
xcopy "%fp%\%CODE%\%CODE%-*-%VER%\%CODE%-DATA.pdf" "%HOMEPATH%\Desktop\Backup\%CODE%\" /D /E /C /I /Y /H
start "" "%HOMEPATH%\Desktop\Backup\%code%"
This is assuming the later versioned directories are always created after the previous versions:
#echo off
set fp=<SET YOUR FILEPATH HERE>
set /p "code=Input Control Number: "
set cnt=0
:start
for /f "delims=" %%a in ('dir /b /s /ad /o-d "%fp%\%code%" ^| findstr "%code%" ^|more +%cnt%') do (
if exist "%%~a\%code%-DATA.pdf" (
set "found=%%~a"
goto :done
) else (
if %cnt% equ 10 goto :eof
set /a cnt+=1
goto start
)
)
:done
set cnt=
xcopy "%found%\%code%-DATA.pdf" "%USERPROFILE%\Desktop\Backup\%code%\" /D /E /C /I /Y /H
start "" "%USERPROFILE%\Desktop\Backup\%code%"
We really just check the latest folder for the file, if it does not exist, we skip that folder and try and older version until we find it, then copy the file.
I am writing a batch file to read all the files within the folder.
Below is my code:
#echo off
setlocal EnableDelayedExpansion
for %%I in (C:\test\*.print_job.*) do (
Set Name=%%~nxI
echo !Name!
)
pause
I am able to get all the .print_job files but now I want to read all the files and look for a specific identifier.
if the file contains "MOUNT" then move that file to C:\Folder1
if the file contains "PROD" then the file should get moved to
C:\Folder2
if the file contains "SPI" then the file should get moved to
C:\Folder3
Thanks in advance
#echo off
rem string target destination
call :movefiles "MOUNT" "C:\test\*.print_job.*" "C:\Folder1"
call :movefiles "PROD" "C:\test\*.print_job.*" "C:\Folder2"
call :movefiles "SPI" "C:\test\*.print_job.*" "C:\Folder3"
goto :eof
:movefiles
if not exist "%~3" md "%~3"
for /f "delims=" %%A in ('2^>nul findstr /l /m /c:"%~1" "%~2"') do (
move "%%~A" "%~3"
)
goto :eof
Use of call :movefiles to handle each of the 3 strings to
search for in the target files.
Call syntax: call :movefiles <string> <target> <destination>
Makes the destination directory if not exist. If string found
in a target file, the file will be moved into the destination
folder.
The findstr arguments used are:
/l Uses search strings literally.
/m Prints only the filename if a file contains a match.
/c:string Uses specified string as a literal search string.
You can insert rd "%~3" after the for loop if you want to
remove empty destination folders.
To loop every 2 seconds:
#echo off
:main
rem string target destination
call :movefiles "MOUNT" "C:\test\*.print_job.*" "C:\Folder1"
call :movefiles "PROD" "C:\test\*.print_job.*" "C:\Folder2"
call :movefiles "SPI" "C:\test\*.print_job.*" "C:\Folder3"
timeout /t 2 /nobreak >nul
goto :main
:movefiles
if not exist "%~3" md "%~3"
for /f "delims=" %%A in ('2^>nul findstr /l /m /c:"%~1" "%~2"') do (
echo move "%%~A" "%~3"
)
goto :eof
You may need to use Ctrl+C to end the script as it is in a continuous loop.
If you can use a task scheduler instead then that could work.
If a file name with the search word removed is different it had been in there.
#echo off
for %%I in (C:\test\*) do Call :Sub "%%I"
Pause
Goto :Eof
:Sub
Set "Name=%~nx1"
if "%Name%" neq "%Name:MOUNT=%" (move "%~1" "C:\Folder1\" & Goto :Eof)
if "%Name%" neq "%Name:PROD=%" (move "%~1" "C:\Folder2\" & Goto :Eof)
if "%Name%" neq "%Name:SPI=%" (move "%~1" "C:\Folder3\" & Goto :Eof)
I have created a batch file in a windows server to parse the name of the files stored in a folder.
The name of the file contains a set of parameters splitted by the hyphen, e.g.
ACC-INV-APR-2015
I need to check the syntax correctness of the first two parameters (department and document type) e.g. I would avoid that the hyphen is inserted more than a time in the file name.
On the basis of the check, the files with wrong syntax will be moved to a folder.
We have to consider that, apart the first two parameters that are mandatory, the other ones could be skipped and therefore the file name could have some repetitive hypens after the first two parameters, e.g.
FIN-DOC-APR-2015--MFH-P01
We would avoid to have some file name like: FIN--DOC-APR-2015-MFH-P01
I have created the following batch file but I don't know how to skip the filename with wrong syntax....
Thank you.
setlocal EnableDelayedExpansion
set source=\\fileserver\share$\archive
set dest_ok=\\fileserver\share$\fileok
set dest_not=\\fileserver\share$\error
FOR /R %source% %%f in (*.*) do call :Proc1 "%%f"
goto End
:Proc1
Set filename=%1%
For %%A in (%filename%) do (
Set Folder="%%~dpA"
Set Name=%%~nxA
)
for /f "tokens=1,2 delims=- " %%a in ("%Name%") do call :Proc2 %%a %%b
goto :eof
:Proc2
set department=%1
set typedoc=%2
FINDSTR /x "%department%" c:\0_scripts\arch\departments.txt
if %errorlevel%==0 FINDSTR /x "%typedoc%" c:\0_scripts\arch\typedocs.txt
if %errorlevel%==0 move /Y %filename% %dest_ok%
if %errorlevel%==1 move /Y %filename% %dest_not%
goto :eof
:End
Sounds like a job for regular expressions. The Windows utility findstr will let you match based on a regular expression. It exits status 0 if found, non-zero otherwise. This lends itself to conditional execution. In a cmd console, enter findstr /? for details on supported regexp syntax.
It'll also speed things up to cache the contents of departments.txt and typedocs.txt into variables, rather than open, read, close, repeat for each file checked.
So, with that in mind, here's how I'd do it:
#echo off
setlocal
set "source=\\fileserver\share$\archive"
set "dest_ok=\\fileserver\share$\fileok"
set "dest_not=\\fileserver\share$\error"
set "departments.txt=c:\0_scripts\arch\departments.txt"
set "typedocs.txt=c:\0_scripts\arch\typedocs.txt"
setlocal enabledelayedexpansion
for /f "usebackq delims=" %%I in ("%departments.txt%") do set "dept=%%~I;!dept!"
for /f "usebackq delims=" %%I in ("%typedocs.txt%") do set "type=%%~I;!type!"
endlocal & set "dept=%dept%" & set "type=%type%"
for /r "%source%" %%I in (*) do (
rem // Does filename match /^[a-z]+-[a-z]+/i ?
echo %%~nxI | findstr /i "^[a-z][a-z]*-[a-z][a-z]*" >NUL && (
rem // Yep. Check whether department and doc type is in allowed list.
for /f "tokens=1-2 delims=- " %%a in ("%%~nxI") do (
// if %dept% doesn't equal itself with %%~a removed, and so on...
setlocal enabledelayedexpansion
if not "%dept%"=="!dept:%%~a=!" if not "%type%"=="!type:%%~b=!" (
// All checks passed. Moved to OK folder.
move /y "%%~fI" "%dest_ok%"
)
endlocal
)
)
// If the file hasn't been moved by now, it must've failed a test.
if exist "%%~fI" move /y "%%~fI" "%dest_not%"
)
C:\0_scripts\arch>(
echo MFH3-FHW-20150529-F001MD14895-20301231-V01-OP20-TRIFLEX-CP1_H--.pdf | findstr /i "^[a-z][a-z]*-[a-z][a-z]*" 1>N
UL && (for /F "tokens=1-2 delims=- " %a in ("MFH3-FHW-20150529-F001MD14895-20301231-V01-OP20-TRIFLEX-CP1_H--.pdf") do (
setlocal enabledelayedexpansion
if not "TEF6;TEF10;QMM8;QMM73;QMM72;QMM71;QMM7;QMM6;QMM13;QMM1;QMM;MFP2;MFP1;MFH3;MFH2;MFH1;MFH ;MFG3;MFG22;MFG21;MFG2;
MFG11;MFG1;MFG;MFB;HSE;COS;" == "!dept:%~a=!" if not "WPL;WP;WBP;WB;WAL;WAG;WA;VTL;VTK;VDP;VBT;VBL;VB;VAW;VAP;VA;UVA;UMV
;TSS;TRN;TKU;TDC;SYM;SWD;SWC;SW;SVS;SVA;SV;STR;STL;STF;STB;SPC;SBT;SAM;RTZ;RTP;RPL;RP;RNO;RHW;RAW;QMP;QMA;QM;QBG;QB;QAM;
PZB;PUM;PRV;PRS;PRJ;PRA;PQP;PPM;PPK;PP;PNR;PLB;PH;PFH;PDV;PDR;PDC;PDB;PAP;PAL;PAG;OPS;OPL;OEE;NOR;NKA;MUB;MSZ;MON;MOD;MB
B;MNT;LZT;LZS;LZN;LPV;LPN;LPL;LPC;LPA;LHT;LDP;LBA;KSB;KPV;KPA;KOE;KOB;KBU;KBL;KB;IAM;HZG;HZ;HSE;HRB;HFG;HF;HE;HAZ;GMD;GE
Z;GBB;FVT;FRM;FPL;FPK;FPI;FPA;FP;FMP;FME;FMD;FMA;FLP;FLB;FIM;FHW;FGY;FGV;FGS;FGP;FGL;FGK;FGE;FGD;FGB;FGA;FDA;FA;EZZ;EWZ;
EWS;EVT;EV;ETZ;ETL;ESZ;EPB;EP;ECM;DVL;ECR;DV;DRX;DRW;DRV;DRQ;DRK;DRF;DMD;DIF;DLP;DER;DDI;DBL;DB;DAT;D01;CPC;CIP;CHL;CE;C
AP;BVT;BVS;BVB;BV;BUG;BSV;BST;BSS;BS;BPZ;BLD;BDL;BBL;BBD;BB;BAL;BAD;ANH;AGZ;AFK;AEN;AED;AAW;AA;" == "!type:%~b=!" (
move /y "\\server1\digit$\deposito\MFH3\MFH3-FHW-20150529-F001MD14895-20301231-V01-OP20-TRIFLEX-CP1_H--.pdf" "\\server1\digit$\errori"
pause
)
endlocal
) )
if exist "\\server1\digit$\deposito\MFH3\MFH3-FHW-20150529-F001MD14895-20301231-V01-OP20-TRIFLEX-CP1_H--.pdf" move
/y "\\server1\digit$\deposito\MFH3\MFH3-FHW-20150529-F001MD14895-20301231-V01-OP20-TRIFLEX-CP1_H--.pdf" "\\server11\digit$\ok"
pause
)
1 file(s) moved.
Press any key to continue . . .
Blockquote
I have changed the script and came back to your original version .
This is the output of the batch file when a file correct is processed:
if exist "\server1\digit$\deposito\MFH3\MFH3--FHW-20150512-F01MD14861-20301231-V02-OP20-TRIFLEX-CP1H--.pdf" move
/y "\server1\digit$\deposito\MFH3\MFH3--FHW-20150512-F01MD14861-20301231-V02-OP20-TRIFLEX-CP1H--.pdf" "\server1\
digit$\errori"
pause
)
1 file(s) moved.
Press any key to continue . . .
C:\0_scripts\arch>(
echo MFH3-AFK-20150511-F01MD12340-20301231-V07-OP20-TRIFLEX-CP1_H--.pdf | findstr /i "^[a-z][a-z]-[a-z][a-z]" 1>NU
L && (for /F "tokens=1-2 delims=- " %a in ("MFH3-AFK-20150511-F01MD12340-20301231-V07-OP20-TRIFLEX-CP1_H--.pdf") do (
setlocal enabledelayedexpansion
if not "TEF6;TEF10;QMM8;QMM73;QMM72;QMM71;QMM7;QMM6;QMM13;QMM1;QMM;MFP2;MFP1;MFH3;MFH2;MFH1;MFH ;MFG3;MFG22;MFG21;MFG2;
MFG11;MFG1;MFG;MFB;HSE;COS;" == "!dept:%~a=!" if not "WPL;WP;WBP;WB;WAL;WAG;WA;VTL;VTK;VDP;VBT;VBL;VB;VAW;VAP;VA;UVA;UMV
;TSS;TRN;TKU;TDC;SYM;SWD;SWC;SW;SVS;SVA;SV;STR;STL;STF;STB;SPC;SBT;SAM;RTZ;RTP;RPL;RP;RNO;RHW;RAW;QMP;QMA;QM;QBG;QB;QAM;
PZB;PUM;PRV;PRS;PRJ;PRA;PQP;PPM;PPK;PP;PNR;PLB;PH;PFH;PDV;PDR;PDC;PDB;PAP;PAL;PAG;OPS;OPL;OEE;NOR;NKA;MUB;MSZ;MON;MOD;MB
B;MNT;LZT;LZS;LZN;LPV;LPN;LPL;LPC;LPA;LHT;LDP;LBA;KSB;KPV;KPA;KOE;KOB;KBU;KBL;KB;IAM;HZG;HZ;HSE;HRB;HFG;HF;HE;HAZ;GMD;GE
Z;GBB;FVT;FRM;FPL;FPK;FPI;FPA;FP;FMP;FME;FMD;FMA;FLP;FLB;FIM;FHW;FGY;FGV;FGS;FGP;FGL;FGK;FGE;FGD;FGB;FGA;FDA;FA;EZZ;EWZ;
EWS;EVT;EV;ETZ;ETL;ESZ;EPB;EP;ECM;DVL;ECR;DV;DRX;DRW;DRV;DRQ;DRK;DRF;DMD;DIF;DLP;DER;DDI;DBL;DB;DAT;D01;CPC;CIP;CHL;CE;C
AP;BVT;BVS;BVB;BV;BUG;BSV;BST;BSS;BS;BPZ;BLD;BDL;BBL;BBD;BB;BAL;BAD;ANH;AGZ;AFK;AEN;AED;AAW;AA;" == "!type:%~b=!" (
move /y "\server1\digit$\deposito\MFH3\MFH3-AFK-20150511-F01MD12340-20301231-V07-OP20-TRIFLEX-CP1_H--.pdf" "\bars
rv11\digit$\ok"
pause
)
endlocal
) )
if exist "\server1\digit$\deposito\MFH3\MFH3-AFK-20150511-F01MD12340-20301231-V07-OP20-TRIFLEX-CP1_H--.pdf" move
/y "\server1\digit$\deposito\MFH3\MFH3-AFK-20150511-F01MD12340-20301231-V07-OP20-TRIFLEX-CP1_H--.pdf" "\server1\
digit$\errori"
pause
)
1 file(s) moved.
Press any key to continue . . .
Given two directories c:\foo and c:\bar I want to delete the files in c:\bar that are identical to files present in c:\foo. I can use the fc command to compare each file in c:\bar with a file of the same name in c:\foo and delete duplicates manually. Is there a simple way to automate this using CMD?
If identical means similar or alike in every way: in every way, not only in date and size, therefore forced binary comparison:
#ECHO OFF >NUL
SETLOCAL enableextensions
pushd "D:\bat\FooBar"
for /F "delims=" %%G in ('dir /B /A:-D *.*') do (
call :proFC "%%~fG" "D:\bat\FooFoo\%%~nxG"
)
popd
ENDLOCAL
goto :eof
:raiseerror
exit /B %1
:proFC
call :raiseerror 321
fc /B "%~1" "%~2" >NUL 2>&1
if %errorlevel% EQU 0 (
echo del "%~1"
) else (
echo %errorlevel% "%~2"
)
goto :eof
Commented crucial points in the above script:
pushd ... switches current working directory
for /F ... loop treats static file list of the Bar folder
call :proFC ... with properly quoted line arguments parameters
popd switches current working directory back
goto :eof ends the script
:raiseerror subroutine returns exit code via exit /B %1
:proFC productive subroutine
call :raiseerror 321 important as For an invalid switch (with two passed files) an error message is printed but the errorlevel is not changed
fc /B "%~1" "%~2" >NUL 2>&1 output and error messages redirected to NUL as the errorlevel is important;
if %errorlevel% EQU 0 (
echo del "%~1" a file delete merely _echo_ed for debugging purposes
) else (
echo %errorlevel% "%~2" for debugging purposes (see below).
goto :eof returns from the subroutine
FC will set an ErrorLevel as follows (but see a note at the call :raiseerror 321 point):
-1 Invalid syntax (e.g. only one file passed)
0 The files are identical.
1 The files are different.
2 Cannot find at least one of the files.
#echo off
cd c:\bar
for %%a in (*.*) do for %%b in ("c:\foo\%%a") do (
if exist "%%b" (
if "%%~Ta %%~Za" equ "%%~Tb %%~Zb" (
del "%%a"
) else (
fc "%%a" "%%b" > NUL
if not errorlevel 1 del "%%a"
)
)
)
If two files may have different modification dates but be equal, remove the %%~T.. parts in the comparison.