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
Related
I was trying this, it'll count file's line after I copy the file's path (Shift+right click >copy as path) and put it in batch file, but.... how do I fix it??
the last \ in %path% is causing problem.
#echo off
Setlocal EnableDelayedExpansion
set /p ifilename=Enter file name:
for %%f in (%ifilename%) do (
set paath=%%~df%%~pf
set ifilename=%%~nf%%~xf
)
echo %paath%
echo %ifilename%
for /f "usebackq" %%a in (`dir /b /s %1 "%paath%"`) do (
for /f "usebackq" %%b in (`type %ifilename% ^| find "" /v /c`) do (
set lines= %%b
)
)
echo %lines%
pause
>> the last \ in %path% is causing problem
It's easy to solve this , the code is :
set TempDir=C:\0TEMP
#echo off
md %TempDir%
cd /d %TempDir%
::------
#echo off
#echo on
Setlocal EnableDelayedExpansion
::set /p ifilename=Enter file name:
SET DUMMYexe=%TempDir%\DUMMY.exe
IF EXIST "%DUMMYexe%" goto ll123
ECHO ---------writing
pause
(
ECHO pause1
ECHO pause2
ECHO pause3
) > %DUMMYexe%
:ll123
SET ifilename=%DUMMYexe%
for %%f in (%ifilename%) do (
set fpath=%%~df%%~pf
set ifilename=%%~nf%%~xf
)
echo %fpath%
echo %ifilename%
SET v=asdf1234
SET vv=\%v%
SET vvv=%fpath%%vv%
CALL SET v=%%vvv:\%vv%=%%
echo 111---%v%
pause
set fpath=%v%
for /f "usebackq" %%a in (`dir /b /s %1 "%fpath%"`) do (
for /f "usebackq" %%b in (`type %ifilename% ^| find "" /v /c`) do (
set lines= %%b
)
)
echo %lines%
echo on
pause
goto
But of course, if I use the var 'path', my win10 will report :
'find' is not recognized as an internal or external command, operable program or batch file.
BTW, Maybe you'd be interested in the code below :
SETLOCAL ENABLEDELAYEDEXPANSION
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`dir `) DO (
SET var!count!=%%F
SET /a count=!count!+1
)
ECHO -------------- %count%
ECHO
ECHO %var1%
ECHO %var2%
ECHO %var3%
ENDLOCAL
pause
which I tested after copying from:
How to set commands output as a variable in a batch file
Very useful info about "Setlocal EnableDelayedExpansion" can be found in:
How do SETLOCAL and ENABLEDELAYEDEXPANSION work?
I have a working Windows batch script which combines multiple CSV files with same headers into one big CSV file. It is as follows:
#echo off
ECHO Set working directory
pushd %~dp0
ECHO Deleting existing combined file
del combined.csv
setlocal ENABLEDELAYEDEXPANSION
set cnt=1
for %%i in (*.csv) do (
if !cnt!==1 (
for /f "delims=" %%j in ('type "%%i"') do echo %%j >> combined.csv
) else if %%i NEQ combined.csv (
for /f "skip=1 delims=" %%j in ('type "%%i"') do echo %%j >> combined.csv
)
set /a cnt+=1
)
I want the output file to be the same name as the folder name, instead of combined.csv.
For example, if the name of the folder is ABC, then output combined CSV file should be ABC.csv.
#echo off
setlocal enableextensions disabledelayedexpansion
pushd "%~dp0"
set "first=1"
for %%a in ("%~dp0\.") do (
del "%%~nxa.csv" 2>nul
(for %%i in (*.csv) do (
if /i not "%%~nxi"=="%%~nxa.csv" if defined first (
set "first="
type "%%~fi"
) else (
(for /f "skip=1 usebackq delims=" %%j in ("%%~fi") do echo(%%j)
)
)) > "%%~fa\%%~nxa.csv"
)
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]
Using Windows Batch script, I need the output as shown below. Please help.
Input:
APP "Default Web Site/" (applicationPool:DefaultAppPool)
APP "Default Web Site/App1" (applicationPool:App1)
APP "Default Web Site/App1/Pages" (applicationPool:App1)
App "Site1/App2/" (applicationPool:App2)
App "Site1/App3/VD1" (applicationPool:VD1)
Output:
Default Web Site
Site1
This works with the sample data.
#echo off
(for /f "delims=/" %%a in (file.txt) do (
for /f "tokens=1,*" %%b in ("%%~a") do (
echo %%~c
)
))>temp.fil
sort <temp.fil |uniq
del temp.fil
pause
The code below is uniq.bat
Place uniq.bat in the same folder as the batch file above or in a directory on the path.
#if (#CodeSection == #Batch) #then
#CScript //nologo //E:JScript "%~F0" & goto :EOF & Rem aacini 2013
#end
var line, prevLine = "";
while ( ! WScript.Stdin.AtEndOfStream ) {
line = WScript.Stdin.ReadLine();
if ( line != prevLine ) {
WScript.Stdout.WriteLine(line);
prevLine = line;
}
}
#echo off
setlocal
set "arg_two=%~2"
for /f "tokens=1 delims=/" %%a in ("%arg_two%") do echo %%a
endlocal
test:
outputparser.bat APP "Default Web Site/" (applicationPool:DefaultAppPool)
>Default Web Site
outputparser.bat App "Site1/App3/VD1" (applicationPool:VD1)
>Site1
But if you set quotes around the input it will not work.
EDIT with a file to process (content is the same as in the question):
#echo off
setlocal
set "file_to_process=.\input_file.txt"
for /f "usebackq tokens=1 delims=(" %%W in ("%file_to_process%") do (
for /f usebackq^ tokens^=2^ delims^=/^" %%a in ('%%~W') do (
echo %%a
)
)
endlocal
#echo off
setlocal enableextensions enabledelayedexpansion
set "inputFile=c:\somewhere\file.dat"
rem Extract the required part of the lines
set "tempFile=%temp%\%~nx0.%random%.tmp"
> "%tempFile%" (
for /f usebackq^ tokens^=2^ delims^=^/^" %%a in ("file.txt") do (echo(%%a)
)
rem Remove the duplicates from the list
set "previous="
for /f "tokens=*" %%f in ('type "%tempFile%" ^| sort') do (
if not "%%f"=="!previous!" (
echo(%%f
set "previous=%%f"
)
)
rem Cleanup
del "%tempFile%" >nul 2>nul
endlocal
It uses the quotes and slashes as delimiters to cut the lines on the required points. Then the list is sorted to eliminate duplicates from the output
#echo off
setlocal enableDelayedExpansion
set "val="
for /f tokens^=2^ delims^=/^" %%A in ('sort input.txt') do (
if "!val!" neq "%%A" echo %%A
set "val=%%A"
)
In the unlikely event that a value may contain !, then you would need
#echo off
setlocal disableDelayedExpansion
set "val="
for /f tokens^=2^ delims^=/^" %%A in ('sort input.txt') do (
set "new=%%A"
setlocal enableDelayedExpansion
if "!val!" neq "!new!" echo !new!
endlocal
set "val=%%A"
)
I have a long list of individual songs not in folders just songs, and I'd like to move them to the folder of theire artist. the songs are in the following format
artist - songname.flac
I can store them in a list, and echo it, but splitting the artist and songname in 2 vars, I can't seem to figure out.
Could someone help me with the splitting (or if you want even with the rest of the script)
this is what I have so far:
#echo off
setlocal enabledelayedexpansion
set N=0
for %%i in (*) do (
set Files[!N!]=%%~ni
set /a N+=1
)
for /l %%x in (1,1,%N%) do echo.!Files[%%x]!
pause
set SOURCE=c:\temp\test
for /f "delims=-. tokens=1,2" %%i in ('dir /b "%SOURCE%\*.flac"') do echo Artist : %%i Song : %%j
update for full script (got to check if it works with space and special chars in path) :
#echo off
setlocal enabledelayedexpansion
set SOURCE=c:\temp\test
set DESTINATION=c:\temp\test
for /f "tokens=*" %%i in ('dir /b "%SOURCE%\*.flac"') do call :OrderThatMess "%%i"
:OrderThatMess
set NAME=%1
for /f "tokens=1,2 delims=-. " %%j in (%1) do (
set ARTIST=%%j
set TITLE=%%k
if not exist "%DESTINATION%\%ARTIST%" (md "%DESTINATION%\%ARTIST%" )
copy %SOURCE%\%NAME% "%DESTINATION%\%ARTIST%\%TITLE%.flac"
)
#echo OFF &SETLOCAL ENABLEDELAYEDEXPANSION
for %%i in (*.flac) do (
set /a N+=1
FOR /f "tokens=1,2 delims=- " %%o IN ("%%~ni") DO (
set "FilesA[!N!]=%%~o"
set "FilesB[!N!]=%%~p"
)
)
for /l %%x in (1,1,%N%) do echo(!FilesA[%%x]! !filesB[%%x]!
Thanks for the answers ;) Thanks to Kayasax I fixed it
here is the full code:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set SOURCE=C:\music\folder\with\files\
for /f "tokens=1,2 delims=-" %%i in ('dir /b "%SOURCE%\*.flac"') do (
set "folder=%%i"
IF NOT EXIST "%SOURCE%\%%i" (
mkdir "%%i"
)
move "%SOURCE%\%%i-%%j" "%SOURCE%\!folder:~0, -1!\%%i-%%j"
)
pause