Hello i have a batch script but i cant work out how to change the path to scan all subfolders within the directory.
In other words i dont want -
C:\Users\ally\Desktop\Documents\Table\CSV versions\2014\
but rather:
C:\Users\ally\Desktop\Documents\Table\CSV versions
as there are lots of different years of data in seperate folders.
Also to note within year folder there are month folders and within that there are the csv files.
#echo off
setlocal enabledelayedexpansion
set "target=C:\Users\ally\Desktop\Documents\All"
cd /d "C:\Users\ally\Desktop\Documents\Table\CSV versions\2014\"
for /L %%a in (101,1,148) do (
set num=%%a
del "%target%\-!num:~-2!.csv" 2>nul
>"%target%\-!num:~-2!.csv.txt" echo Type,angle,edge,Date,Frame,Sum,Mafe,Comp,Rim,Dose,Ell,Role
)
for %%a in (*.csv) do (
for /f "skip=1 usebackq delims=" %%b in ("%%a") do (
for /f "tokens=1,2 delims=-," %%c in ("%%b") do (
set "line=%%c"
if /i "!line:~0,2!"=="HH" >> "%target%\-%%d.csv.txt" echo %%b
)
)
)
ren "%target%\*.csv.txt" *.
pause
To process every folder under the All tree then you can use a for /d /r loop and pushd/popd to set the current folder.
This assumes that every folder has the files you want to process.
Test this on a copy of your data and change the folder to point to it.
You seem to be deleting .csv files, creating .csv.txt files and then trying to process *.csv in the lower loop. Should that be *.csv.txt ?
#echo off
setlocal enabledelayedexpansion
for /d /r "c:\Users\ally\Desktop\Documents\All" %%z in (*) do (
pushd "%%z"
for /L %%a in (101,1,148) do (
set num=%%a
del "-!num:~-2!.csv" 2>nul
>"-!num:~-2!.csv.txt" echo Type,angle,edge,Date,Frame,Sum,Mafe,Comp,Rim,Dose,Ell,Role
)
for %%a in (*.csv) do (
for /f "skip=1 usebackq delims=" %%b in ("%%a") do (
for /f "tokens=1,2 delims=-," %%c in ("%%b") do (
set "line=%%c"
if /i "!line:~0,2!"=="HH" >> "-%%d.csv.txt" echo %%b
)
)
)
ren "*.csv.txt" *.
popd
)
pause
Try adding another loop that will walk down the directory tree and if it finds a csv file, it will process it:
#echo off
setlocal enabledelayedexpansion
set "target=C:\Users\ally\Desktop\Documents\All"
for /f "tokens=1* delims=" %%D in ('dir /s /b /o:-n /a:d "C:\Users\ally\Desktop\Documents\Table\CSV versions"') do (
cd /d "%%~fD"
if exist *.csv (
for /L %%a in (101,1,148) do (
set num=%%a
del "%target%\-!num:~-2!.csv" 2>nul
>"%target%\-!num:~-2!.csv.txt" echo Type,angle,edge,Date,Frame,Sum,Mafe,Comp,Rim,Dose,Ell,Role
)
for %%a in (*.csv) do (
for /f "skip=1 usebackq delims=" %%b in ("%%a") do (
for /f "tokens=1,2 delims=-," %%c in ("%%b") do (
set "line=%%c"
if /i "!line:~0,2!"=="HH" >> "%target%\-%%d.csv.txt" echo %%b
)
)
)
ren "%target%\*.csv.txt" *.
)
)
pause
Explanation of the dir switches:
/s - Displays files in specified directory and all subdirectories.
/b - Uses bare format (no heading information or summary).
/o:in - Lists the files in reverse order
/a:d - Displays only folders
Explanation of the %%~fD: expands %A to a fully qualified path name (from for /?)
Related
I need to combine all csv files data into single csv file using batch script
the folder structure is as follows
C:\Users\username\Desktop\DLog\Export\20200727\AL-Comp_Outbound\20200726\ (multiple csv's present here)
So under "Export" there are multiple folders like "20200727...20200678" and in those folders the common sub folder name is AL-Comp_Outbound which further has a sub folder "20200728...20200728" that contain csv files.
I need to find the folder with name AL-Comp_Outbound navigate to it and then parse through all the sub folders that has csv files and combine it together.
i tried to do but it with below query but it search for all the folders present in the directory, I need only need csv files from all folders having common name as "AL-Comp_Outbound". Also need to remove repetition header
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
PUSHD "%~dp0"
SET "SUMMARY_FILE=sumfile.csv"
DEL /F "%SUMMARY_FILE%" 2>nul
SET "LINE_COUNT=1"
FOR /F "usebackq delims=" %%p IN (`dir c:\ /s /b /ad ^| find "AL-Comp_Outbound"`) DO (
FOR /F "tokens=*" %%f IN ('DIR /S /B *.csv 2^>nul') DO (
FOR /F "usebackq tokens=* eol=ÿ" %%s IN ("%%~f") DO (
>>"%SUMMARY_FILE%" ECHO !LINE_COUNT!%%s
SET /A LINE_COUNT+=1
)
)
)
POPD
ENDLOCAL
Any help is truly appreciated !!!
===============================================================
Below is the code which i tried to get it work but it keeps on going to another folder "AL-Comp_NetworkShare" to fetch CSV file while i only need csv files from sub directories in "AL-Comp_Outbound"
REM #echo off
SETLOCAL ENABLEDELAYEDEXPANSION
PUSHD "%~dp0"
SET "SUMMARY_FILE=sumfile.csv"
DEL /F "%SUMMARY_FILE%" 2>nul
SET "LINE_COUNT=1"
For /D %%G In ("%UserProfile%\Desktop\DLPLog\Export\*") Do For /D %%H In ("%%G\AL-Comp_Outbound\*")Do (PushD %%H,
FOR /F "tokens=*" %%f IN ('DIR /S /B *.csv 2^>nul') DO (
FOR /F "usebackq tokens=* eol=ÿ" %%s IN ("%%~f") DO (
>>"%SUMMARY_FILE%" ECHO !LINE_COUNT!%%s
SET /A LINE_COUNT+=1
)
)
,POPD)
ENDLOCAL
==================================output=================
PS C:\Users\username\Desktop\DLPLog\Export> .\me.bat
C:\Users\username\Desktop\DLPLog\Export>REM #echo off
C:\Users\username\Desktop\DLPLog\Export>SETLOCAL ENABLEDELAYEDEXPANSION
C:\Users\username\Desktop\DLPLog\Export>PUSHD "C:\Users\username\Desktop\DLPLog\Export\"
C:\Users\username\Desktop\DLPLog\Export>SET "SUMMARY_FILE=sumfile.csv"
C:\Users\username\Desktop\DLPLog\Export>DEL /F "sumfile.csv" 2>nul
C:\Users\username\Desktop\DLPLog\Export>SET "LINE_COUNT=1"
C:\Users\username\Desktop\DLPLog\Export>For / %G In ("C:\Users\username\Desktop\DLPLog\Export\*") Do For / %H In ("%G\AL-Comp_Outbound\*") Do (
PushD %H,
FOR /F "tokens=*" %f IN ('DIR /S /B *.csv 2>nul') DO (FOR /F "usebackq tokens=* eol= " %s IN ("%~f") DO (
ECHO !LINE_COUNT!%s 1>>"sumfile.csv"
SET /A LINE_COUNT+=1
) )
POPD
)
C:\Users\username\Desktop\DLPLog\Export>For / %H In ("C:\Users\username\Desktop\DLPLog\Export\20200722\AL-Comp_Outbound\*") Do (
PushD %H,
FOR /F "tokens=*" %f IN ('DIR /S /B *.csv 2>nul') DO (FOR /F "usebackq tokens=* eol= " %s IN ("%~f") DO (
ECHO !LINE_COUNT!%s 1>>"sumfile.csv"
SET /A LINE_COUNT+=1
) )
POPD
)
C:\Users\username\Desktop\DLPLog\Export>For / %H In ("C:\Users\username\Desktop\DLPLog\Export\20200723\AL-Comp_Outbound\*") Do (
PushD %H,
FOR /F "tokens=*" %f IN ('DIR /S /B *.csv 2>nul') DO (FOR /F "usebackq tokens=* eol= " %s IN ("%~f") DO (
ECHO !LINE_COUNT!%s 1>>"sumfile.csv"
SET /A LINE_COUNT+=1
) )
POPD
)
C:\Users\username\Desktop\DLPLog\Export>For / %H In ("C:\Users\username\Desktop\DLPLog\Export\20200724\AL-Comp_Outbound\*") Do (
PushD %H,
FOR /F "tokens=*" %f IN ('DIR /S /B *.csv 2>nul') DO (FOR /F "usebackq tokens=* eol= " %s IN ("%~f") DO (
ECHO !LINE_COUNT!%s 1>>"sumfile.csv"
SET /A LINE_COUNT+=1
) )
POPD
)
C:\Users\username\Desktop\DLPLog\Export>For / %H In ("C:\Users\username\Desktop\DLPLog\Export\20200725\AL-Comp_Outbound\*") Do (
PushD %H,
FOR /F "tokens=*" %f IN ('DIR /S /B *.csv 2>nul') DO (FOR /F "usebackq tokens=* eol= " %s IN ("%~f") DO (
ECHO !LINE_COUNT!%s 1>>"sumfile.csv"
SET /A LINE_COUNT+=1
) )
POPD
)
C:\Users\username\Desktop\DLPLog\Export>(
PushD C:\Users\username\Desktop\DLPLog\Export\20200725\AL-Comp_Outbound\20200715,
FOR /F "tokens=*" %f IN ('DIR /S /B *.csv 2>nul') DO (FOR /F "usebackq tokens=* eol= " %s IN ("%~f") DO (
ECHO !LINE_COUNT!%s 1>>"sumfile.csv"
SET /A LINE_COUNT+=1
) )
POPD
)
The system cannot find the path specified.
C:\Users\username\Desktop\DLPLog\Export>(FOR /F "usebackq tokens=* eol= " %s **IN ("C:\Users\username\Desktop\DLPLog\Export\20200722\AL-Comp_NetworkShare\20200702\20200702_Ncomp-fjt03063.csv")** DO (
ECHO !LINE_COUNT!%s 1>>"sumfile.csv"
SET /A LINE_COUNT+=1
) )
This simple and straightforward Batch file should work:
#echo off
setlocal EnableDelayedExpansion
rem Go to base folder
cd C:\Users\username\Desktop\DLog\Export
rem Process all folders here
for /D %%a in (*) do (
rem Enter to each folder AND to the desired subfolder
pushd "%%a\AL-Comp_Outbound"
rem Parse through all subfolders here
for /D %%b in (*) do (
rem Combine all .csv files in each subfolder
for %%f in ("%%b\*.csv") do (
if not exist sumfile.tmp (
copy "%%f" sumfile.tmp
) else (
more +1 "%%f" >> sumfile.tmp
)
)
)
rem Go back to base folder
popd
)
I have the following batch file:
#echo off
for /f "delims=" %%F in (
'dir /b /a-d [*]*'
) do for /f "tokens=1* delims=]" %%A in (
"%%F"
) do for /f "tokens=*" %%C in ("%%B") do ren "%%F" "%%C"
I want launch it in the root directory and have it go through all directories and subdirectories performing the actions.
I tried adding /D and /r to the 'for' lines, but it doesn't appear to be working.
Do I need add something like...
for /D /r do
under the #echo off ?
Use either dir or for to get all the files, don't mix it up.
When using dir /S for recursive enumeration, regard that full paths are output rather than pure file names only.
This should do it:
#echo off
for /f "delims=" %%F in (
'dir /s /b /a-d [*]*'
) do for /f "tokens=2* delims=]" %%B in (
"%%~nxF"
) do for /f "tokens=*" %%C in ("%%B") do ren "%%~F" "%%C"
So I just changed the following in your original code:
added /s to dir (returns full paths then);
improved second for options (you never used the first token %%A, so why extract it then?);
replaced set %%F of second for by %%~nxF to just parse the file name (type for /? for details concerning substitution modifiers such as ~n, ~x);
replaced source argument "%%F" of ren command by "%%~F" to not fall into double-double-quote problems (the ~ modifier removes potential double-quotes);
You are using "dir" for the enumeration of files, so add "/s" to the DIR command.
I might refactor what you have like this to make it easier to manage.
This also does recursion.
call :TOP .
goto :EOF
:TOP
setlocal
cd "%~f1"
for /f "delims=" %%F in ('dir /b /a-d [*]*') do call :SubRoutine "%%F"
for /D %%x in (*) do call :TOP "%%x" || (echo FAILED2 "%%x" && exit /b 2)
goto :EOF
:SubRoutine
for /f "tokens=1* delims=]" %%A in ("%~1") do call :SubRoutine2 "%~1" "%%A" "%%B"
goto :EOF
:SubRoutine2
for /f "tokens=*" %%C in ("%~3") do ren "%~1" "%%C"
goto :EOF
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 folder into which I do a print to file option and it saves my print job as a pcl file. The software I use to do the print to file names each file in following manner: GUID.XX.pcl where XX is a number.
Example:
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.7.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.8.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.9.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.11.pcl
What I want to do is rename the files so that they look like this:
1.pcl
2.pcl
3.pcl
and so on.
Here is the batch I use:
for %%a in (*.pcl) do (
set /a i+=1
ren "%%a" "!i!.new"
)
ren *.new *.pcl
This works but the problem is,in the example I gave above
It renames
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl to 1.pcl
and
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl to 3.pcl
I need it to rename
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl to 1.pcl
and
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl to 5.pcl
It is basically seeing 10 before 6. Is there some way around this?
for /F "tokens=1-3 delims=." %%a in ('dir /B *.pcl') do (
set /A num=100+%%b
set "name[!num:~1!]=%%a.%%b.%%c"
)
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i!.pcl"
)
If you want to use two digits in the new name, so the order be preserved in dir or for listings, modify the second part this way:
set i=100
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i:~1!.pcl"
)
EDIT: I tested my code and it works correctly. This is the output of the test session:
C:\> dir /b
test.bat
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.11.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.7.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.8.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.9.pcl
C:\> test
C:\> dir /b
1.pcl
2.pcl
3.pcl
4.pcl
5.pcl
6.pcl
test.bat
C:\> type test.bat
#echo off
setlocal EnableDelayedExpansion
for /F "tokens=1-3 delims=." %%a in ('dir /B *.pcl') do (
set /A num=100+%%b
set "name[!num:~1!]=%%a.%%b.%%c"
)
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i!.pcl"
)
not tested:
for %%a in (*.pcl) do (
for /f "tokens=2 delims=}" %%# in ("%%~nxa") do (
ren "%%~fa" "%%#"
)
)
I have the below code which someone gave to me but I don't know how to put it together in a bat file so it runs successfully.
The aim is to find the latest (last modified) file in c:/ and compare it with c:/2.txt and output the differences into c:/786.txt
cd /d c:\
for /f %%a in ('dir /b /o-d /a-d /tw') do (set latest=%%a & goto :eof)
for /f "tokens=1*" %%a in (
'diff c:\%latest% c:\2.txt ^| findstr /r /c:"^<" /c:"^>"'
) do #echo %%b >>c:\786.txt
Can someone please put this code together for me.
cd /d c:\
set "latest="
for /f %%a in ('dir /b /o-d /a-d /tw') do (set "latest=%%a" & goto :found)
:found
if not defined latest exit /b
for /f "tokens=1,*" %%a in (
'diff "c:\%latest%" "c:\2.txt" ^| findstr /r /c:"^<" /c:"^>"'
) do (
>> "c:\786.txt" echo(%%b
)
Ordering by date descending, the latest file is the first, so on first iteration assign the file name and exit of the for loop.
Then check if any file has been found. It not, end of the script
If we have a file, compare latest file against the indicated one and send the filtered lines to the final file.
EDIT - Refactor code to made it more usable and adapt to comments. Search for last file in folder moved to a subroutine.
#echo off
setlocal enableextensions disabledelayedexpansion
call :getLatestFileInFolder "c:\" latestC
call :getLatestFileInFolder "d:\" latestD
if not defined latestC ( echo NO File in C & exit /b )
if not defined latestD ( echo NO File in D & exit /b )
for /f "tokens=1,*" %%a in (
'diff "%latestC%" "%latestD%" ^| findstr /r /c:"^<" /c:"^>"'
) do (
>> "c:\786.txt" echo(%%b
)
endlocal
exit /b
:getLatestFileInFolder folderToSearch variableToReturn
setlocal
set "folder=%~1" & if not defined folder set "folder=%cd%"
set "latest="
pushd "%folder%"
for /f "tokens=*" %%a in ('dir /b /o-d /a-d /tw 2^>nul') do (set "latest=%%~fa" & goto :latestFileFound)
:latestFileFound
popd
endlocal & set "%~2=%latest%" & goto :eof