Create a folder using substring of filename - batch-file

I want to fetch two sub string from my file name in order to create Folder String.
My file name is "SM-SM-ABC_ab12 cd34_AA 11_abc123.txt"
here "ab12 cd34" is 1st folder and "AA 11" is 2nd folder
I have written a code but After adding #Compo code I ma not able to move file to directory. I want to move multiple files to respective folders.
Can some one help whats wrong?
#Echo Off
set Path1= d:\A
:: SDate=DAYMONTHYEAR FORMAT of Systemdate
echo %Path1%
set SDate=%date:~7,2%%date:~4,2%%date:~10,4%
echo %SDate%
::Variable for folder path
Pushd %Path1%
for %%i in (*.*) do SET "FPath=%%~ni"
For /F "Tokens=2-3 Delims=_" %%A In ("%FPath%") Do (
Set "FoldOne=%%A"
Set "FoldTwo=%%B"
if not exist "%Path1%\%FoldOne%\%FoldOne%\%SDate%" (
mkdir "%Path1%\%FoldOne%\%FoldOne%\%SDate%" )
move %Path1%\* "%Path1%\%FoldOne%\%FoldTwo%\%SDate%\"
echo test %Path1%
echo test %FPath%
)
GoTo :EOF

Is this what you are trying to achieve?
#Echo Off
Set "FPath=SM-SM-ABC_ab12cd34_AA11_abc123.txt"
For /F "Tokens=2-3 Delims=_" %%A In ("%FPath%") Do (
Set "FoldOne=%%A"
Set "FoldTwo=%%B")
Echo(%%FoldOne%%=%FoldOne%
Echo(%%FoldTwo%%=%FoldTwo%
Timeout -1
GoTo :EOF
[Edit /]The following code may provide you with a solution for your updated requirements:
#Echo Off
Set "Path1=D:\A"
If /I Not "%CD%"=="%Path1%" Pushd "%Path1%" 2>Nul || Exit/B
For /F "EOL=L" %%A In ('WMIC OS GET LocalDateTime') Do For %%B In (%%~nA
) Do Set "SDate=%%B"
Set "SDate=%SDate:~6,2%%SDate:~4,2%%SDate:~,4%"
For %%A In ("*_*_*_*.*") Do Call :Sub "%%A"
Timeout -1
GoTo :EOF
:Sub
For /F "Tokens=2-3 Delims=_" %%A In (%1) Do If Not "%%A"=="" If Not "%%B"=="" (
If Not Exist "%%A\%%B\%SDate%\" MD "%%A\%%B\%SDate%"
Move %1 "%%A\%%B\%SDate%")

Related

Checking if an array element(file) has a specific extension

I'm trying to write a code that does the following. I have some files in a directory with specific extensions. I have made a vector that contains all of them. Now I will want to rename each file to something else depending on their extension. So for that I'm trying to parce the created vector with a for loop in which I check for each element extension.
For now I won't rename it just echo it on the screen if the file with the .elf extension is found. I wrote this code but I get no echo as in there would be no .elf file in my directory. Please help me correct this. Thanks.
#echo off
setlocal enabledelayedexpansion
cd C:\Users\uidr0938\Desktop\Copy
set path=C:\Users\uidr0938\Desktop\Copy
set /a index=0
for /r %%i in (*) do (
set value[!index!]=%%i
set /a index+=1
)
set /a limit=%index%-2
for /l %%a in (0;1;%limit%) do (
if !value[%%a]! equ *.elf (
echo !value[%%a]!
)
)
endlocal
try with :
....
for /l %%a in (0;1;%limit%) do (
if "!value[%%a]:~-4!" equ ".elf" (
echo !value[%%a]!
)
)
when comparing string you cannot use wildcards.Here you can see some examples about batch substrings
Here is a slightly different way of doing it.
#IF NOT EXIST "%USERPROFILE%\Desktop\Copy\" #EXIT/B
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "_path=%USERPROFILE%\Desktop\Copy"
SET "_index=0"
FOR /F "DELIMS=" %%A IN ('WHERE/R "%_path%" * 2^>NUL') DO (SET/A "_index+=1"
SET "_value[!_index!]=%%A")
IF %_index% EQU 0 EXIT/B
FOR /F "TOKENS=1* DELIMS==" %%A IN ('SET _value['
) DO IF /I "%%~xB"==".elf" ECHO %%B
PAUSE

Moving files and renameing duplicats

I need to move files from C:\users\users name\documents\sound recordings\ directory to our network drive P:\transcription\users name\. I need the files to automatically get renamed if the file exist in the P:\transcription\users name directory. I am a novice and can only write simple batch files and the one I wrote to move the files will over write the files with the same name in the directory. Thanks
This may help.
It will display files to be moved with resulting filename. If it works ok for you , remove the line echo !src!%%~nxa - !dst!!file! and delete the rem keyword from rem move !src!%%a !dst!!file! >nul
#echo off
SetLocal EnableDelayedExpansion
set "wildcard=*.*" & rem files to search for
set "skipUsers=Guest Administrator" & rem users not to copy files
:: get users
set/a offset=0
for /F "skip=2 tokens=2 delims=," %%1 in ('wmic useraccount get name^,sid /format:csv') do (
set/a offset+=1, USER_MAX=offset
set "USER[!offset!]=%%1"
)
for /L %%i in (1,1,%USER_MAX%) do (
set/a skip=0, numFiles=0
set "currentUser=!USER[%%i]!"
set "src=C:\!currentUser!\documents\sound recordings\"
set "dst=P:\transcription\!currentUser!\"
rem get time stamp
for /f "tokens=2 delims==" %%A in ('wmic os get localdatetime /value') do set "Tm=%%A"
set "timeStamp=!Tm:~0,4!!Tm:~4,2!!Tm:~6,2!_!Tm:~8,2!!Tm:~10,2!!Tm:~12,2!"
for %%a in (%skipUsers%) do if /I "!currentUser!" equ "%%a" set/a skip=1
if !skip! neq 0 ( rem avoid copying blacklist users
echo !currentUser!: Skipping
) else (
<nul set/P="!currentUser!: Moving files"
pushd !src!
dir /ad !dst! >NUL 2>NUL || md !dst! & rem create destination folder if it doesn't exist
for %%a in (%wildcard%) do (
set "file=%%~nxa"
if exist "!dst!!file!" set "file=%%~na_!timeStamp!%%~xa" & rem rem if file exist, append a time stamp suffix to avoid overwriting
echo !src!%%~nxa - !dst!!file!
rem move !src!%%~nxa !dst!!file! >nul
set/a numFiles+=1
)
echo : !numfiles! files moved
popd
)
)
EndLocal
exit/B

Extract date from XML file and move file to directory created from date

I have a directory that contains close to a million XML files. Needless to say, it takes forever to load (20+ minutes) So, I'm writing a script to divide the files into folders with the top level being year and having months under each year. There are 4 main filenames where the date can be extracted from the 3rd token and the rest from the second token. ie:
BA1253570001_BALMIS_20130617_TRC_0_109506738E.xml
BA1254260001_ACCTV21_20140430_AMR_0_1095611492.xml
BA1736330001_SWFTOUT_20140929_LIQ_1_MTBX553494.xml
BA1739240001_FEDOUT_20140904_LIQ_1_105633316M.xml
The rest are like this:
EODMESS_20140718_MTBX473286.xml
MSGCONF_20140410_109558667V.xml
I'm sure there is an easier way to do it, but here is my code so far:
#echo on
setlocal enabledelayedexpansion
Set "starttime=%time%"
pushd C:\temp\xmls
for /f %%a in ('dir /b/o:d *.xml') do (
call :ExtractDates %%a ret
echo %%a - !ret!
for /f "tokens=1" %%b in ("!ret!") do (
for /f "tokens=1-3 delims=/" %%c in ("%%b") do (
if not exist .\%%e md .\%%e
if not exist .\%%e\%%c md .\%%e\%%c
if %%b equ %%c/%%d/%%e (
echo moving %%~nxa to .\%%e\%%c
echo move %%~nxa .\%%e\%%c
pause
)
)
)
)
echo Start time: %starttime%
echo End time: %time%
popd
exit /b
:ExtractDates
#echo on
setlocal enabledelayedexpansion
Echo Starting ExtractDates
for %%a in (BALMIS ACCTV21 FEDOUT SWFTOUT) do (
if not errorlevel 1 (set t=3) else set t=2
Call :ExtractFunc %~1 %%a !t! ret
endlocal&set "%~2=!ret!"&exit /b 0
)
exit /b
:ExtractFunc
#echo on
setlocal
Echo Starting ExtractFunc
for /f "tokens=%3 delims=_" %%a in (
'echo %~1^|Findstr "%~2"'
) do (
if not errorlevel 1 (
endlocal&set "%~4=%%a"&exit /b 0
)
)
exit /b
The problem is that the variable token isn't returning the right number and I'm not sure why. Any suggestions appreciated.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
PUSHD "%sourcedir%"
FOR /f "tokens=1*delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*_*_*.xml" '
) DO SET "filename=%%a"&CALL :process
POPD
GOTO :EOF
:process
FOR /f "tokens=2,3,6delims=_" %%m IN ("%filename%") DO SET "date1=%%m"&SET "date2=%%n"&SET "whichdate=%%o"
IF DEFINED whichdate SET "date1=%date2%"
IF NOT DEFINED date2 GOTO :eof
ECHO(MD .\%date1:~0,4%\%date1:~4,2%
ECHO(MOVE "%filename%" .\%date1:~0,4%\%date1:~4,2%\
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required MD commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MD to MD to actually create the directories. Append 2>nul to suppress error messages (eg. when the directory already exists)
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
Simply extract the two possible datestrings and use the presence of the sixth token to signal which of the two positions to select for generation of the destination directory. Skip if there's no third token (fails to fit mask specified)
Then select the required field to date1 and do some substringing.

Batch file to loop through a directory and create a variable based on each file

I have a text file with a list of server IP addresses and the code below (which I've scrapped together from other coding) loops through it and brings back a modified date of a named file for each server in the list...
#ECHO On
SETLOCAL
FOR /f %%a IN (C:\Scripts\Servers.txt) DO (
CALL :getmod %%a
)
GOTO :EOF
:getmod
SET Server=%1
SET File=Abs_Client.exe
FOR %%i IN ("\\%Server%\C$\Com_Dir\%File%") DO SET modif_time=%%~ti
Echo %Server% %File% %modif_time% >> "C:\Scripts\Server_App_Mod_date.txt"
GOTO :eof
That works great...however, what I'd like to do is create another loop around it which creates a variable for each file in a directory and pass that into the code above instead of having to manually change the 'SET File' as shown above for individual files.
Something along the lines of;
#ECHO On
SETLOCAL
FOR /D %VAR IN ("\\Network_Location\AppMedia\App Source Files\Prod Apps\Server_Update") DO (
FOR /f %%a IN (C:\Scripts\Servers.txt) DO (
CALL :getmod %%a
)
GOTO :EOF
:getmod
SET Server=%1
SET File=%VAR
FOR %%i IN ("\\%Server%\C$\Com_Dir\%File%") DO SET modif_time=%%~ti
Echo %Server% %File% %modif_time% >> "C:\Scripts\Server_App_Mod_date.txt"
GOTO :eof
)
Clearly it's wrong so any ideas/help please?
haven't testet, but maybe a hint in the right direction:
#ECHO ON
SETLOCAL
FOR /F "TOKENS=*" %%F IN ('DIR "\\Network_Location\AppMedia\App Source Files\Prod Apps\Server_Update" /s /b /a:-d') DO (
FOR /F %%A IN (C:\Scripts\Servers.txt) DO (
CALL :getmod %%A "%%~nxF"
)
)
GOTO :EOF
:getmod
SET Server=%1
SET "tmpFile=%~2"
FOR %%I IN ("\\%Server%\C$\Com_Dir\%tmpFile%") DO ECHO %Server% %tmpFile% %%~tI >> "C:\Scripts\Server_App_Mod_date.txt"
GOTO :EOF
As far as i know, FOR /D only executes for directorys and if i understand your question, you have files in "Prod Apps\Server_Update", for each you like to have the file-date/time from the target-server... right?
Edit:
Maybe this works too:
FOR /F "TOKENS=*" %%F IN ('DIR "\\Network_Location\AppMedia\App Source Files\Prod Apps\Server_Update" /s /b /a:-d') DO (
FOR /F %%A IN (C:\Scripts\Servers.txt) DO (
FOR %%X IN ("\\%%A\C$\Com_Dir\%%~nxF") DO ECHO %%A %%~nxF %%~tX >> "C:\Scripts\Server_App_Mod_date.txt"
)
)
without the :getmod
Edit: /b-switch was missing from the first DIR-Command in 2nd suggestion
#ECHO On
SETLOCAL
FOR /f %%a IN (C:\Scripts\Servers.txt) DO (
FOR /f "delims=" %%i IN ('dir /b/a-d "\\%%a\C$\Com_Dir\*"') DO Echo %%a %%i %%~ti >> "C:\Scripts\Server_App_Mod_date.txt"
)
GOTO :EOF
Should work, IIUC. Can't test, I'm afraid...
[Edit - removed call to getmod - not required]

How to get a Substring from list of file names

I want to develop the following logic
Read all files in a directory
Extract the first part of the filename – this will be the partner name
Extract anything after the first underscore- this will be filename
Eg: ZZTEST_123_abc_doc.txt  ZZTEST is partner. 123_abc_doc.txt is the filename.
Below is the code I developed
#echo off
setlocal ENABLEDELAYEDEXPANSION
Set Test_Dir=C:\Axway\projects\Cardinal\dosscript\test
cd %Test_Dir%
for /r %%a in (*.*) do (
Set "fname1=%%~nxa"
echo Filename is :!fname1!
for /f "tokens=1 delims=_" %%i in ("!fname1!") do (
Set "partner=%%i"
echo Partner is :!partner!
Set "str_tmp=!partner!_"
echo !str_tmp!
call :strlength length !str_tmp!
echo !length!
set fname=!fname1:~%length%!
echo !fname1:~%length%!
)
)
goto :eof
:strlength
setlocal enableextensions
set "#=%~2"
set length=0
:stringLengthLoop
if defined # (set "#=%#:~1%"&set /A length+=1&goto stringLengthLoop)
endlocal && set "%~1=%length%"
GOTO :EOF
But the result is
ID_ZZRoutingID_filename.txt
Filename is :ZZRoutingID_ZZRoutingID_filename1.txt
Partner is :ZZRoutingID
12
Result: ID_ZZRoutingID_filename1.txt
The result should be ZZRoutingID_filename1.txt but i am getting
ID_ZZRoutingID_filename1.txt.
Please help
The purpose of the length calculation is not clear to me, but I would suggest adding an asterisk following the 1 in your for /f "tokens=1 delims=_". You would then get the "filename" you were looking for through %%j.
I tested it like this:
#echo off
setlocal EnableDelayedExpansion
set source=D:\Program Files\Somewhere
cd %source%
for /r %%i in (*.*) do (
for /f "tokens=1* delims=_" %%j in ( "%%~nxi" ) do (
echo partner: %%j
echo name: %%k
)
)
endlocal
If you do not need to recurse through sub-directories:
#echo off
set source=D:\Program Files\Somewhere
for /f "tokens=1* delims=_" %%i in ( 'dir "%source%" /b /a-d' ) do (
echo partner: %%i
echo filename: %%j
)
dir /b /a-d retrieves the list of a directory's content except its sub-directories:
D:\Program Files\Somewhere>dir /b /a-d
ZZTEST_123_456.txt
ABCDEF_890_FFF.doc
FOOBAR_567_###.zzz

Resources