Rexx
asked on
Combine multiple .csv into one with file name
The following batch code combines multiple .csv files into one. What additional code would be needed to include the file name.
@echo off
setlocal
set FileMask=C:\Temp\test*.csv
set OutFile=C:\Temp\test_combined.csv
for %%a in ("%FileMask%") do (
for /f "delims=" %%h in ('type "%%a"') do (
>"%OutFile%" echo %%h
goto :Combine
)
)
:Combine
for %%a in ("%FileMask%") do (
echo Processing %%a ...
if /i "%%a"=="%OutFile%" (
echo ... skipped result file.
) else (
more +1 "%%a" >>"%OutFile%"
)
)
echo Done.
ASKER
Rather it be in its own column so that the file name is listed with each record from the file:
Combined.tif
Combined.tif
Is the header line the same in all files, and what does it look like? I think we can use that to take a slightly different approach to get the results you want.
~bp
~bp
ASKER
Yes the header line is the same in all files. The initial script I started with (at the top) just includes the header of the first file. So I'm wanting to add another column to that named "File Name".
Here is code that works the way I want it to but for some records (in the combined file) it has issues keeping the entire field of a column together.
Here is code that works the way I want it to but for some records (in the combined file) it has issues keeping the entire field of a column together.
@echo off
setlocal EnableDelayedExpansion
set FileMask=C:\1_test\*.csv
set OutFile=C:\0_test\combined.csv
set Header=
(for %%F in ("%FileMask%") do (
if not defined header set /P header=<%%F& echo File_Name, !header!
for /F "skip=1 usebackq delims=" %%L in ("%%~F") do echo %%~F, %%L
))>"%OutFile%"
This is pretty close, but not perfect. It does what we want, but the only wrinkle is the filename has a colon after it on each line, rather than a comma. Depending on what you do with the file though, maybe that works?
@echo off
setlocal
set BaseDir=B:\EE\EE28942070\Files
set FileMask=test*.csv
set OutFile=B:\EE\EE28942070\Output\test_combined.csv
pushd "%BaseDir%"
call :GetHeader
call :GetData
popd
echo Done.
exit /b
:GetHeader
for %%F in ("%FileMask%") do (
for /f "delims=" %%H in ('type "%%~F"') do (
set Header=%%H
echo.Filename,%%H>"%OutFile%"
exit /b
)
)
exit /b
:GetData
findstr /v /l /c:"%Header%" "%FileMask%">>"%OutFile%"
exit /b
~bp
ASKER
Unfortunately that won't work because the data in some columns will either get carried over into another column or get added as another "partial" record.
When I do a more +1 this issue goes away.
The following code provides a header and combines the data correctly every time. It even includes a field in the header for "File_Name" (last field of header).
Is there away to get the File_Name included during the combine?
(It doesn't matter whether the File_Name is in the first column or the last column. if it can be added to each record without changing anything else we're done.)
I'm attaching a couple .csv files that have data in fields that cause issues during combine. If you combine these two files with your program you'll see the issues.
test_1.csv
test_2.csv
When I do a more +1 this issue goes away.
The following code provides a header and combines the data correctly every time. It even includes a field in the header for "File_Name" (last field of header).
Is there away to get the File_Name included during the combine?
(It doesn't matter whether the File_Name is in the first column or the last column. if it can be added to each record without changing anything else we're done.)
@echo off
setlocal EnableDelayedExpansion
set FileMask=C:\1_test\*.csv
set OutFile=C:\0_test\combined.csv
For %%F in ("%FileMask%") do (
for /F "delims=" %%H in ('type "%%F"') do (
>"%OutFile%" echo %%H ,File_Name
goto :Combine
)
)
)
:Combine
for %%F in ("%FileMask%") do (
more +1 "%%F" >>"%OutFile%"
)
I'm attaching a couple .csv files that have data in fields that cause issues during combine. If you combine these two files with your program you'll see the issues.
test_1.csv
test_2.csv
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Nice work. I did drop the first four lines and saved it as a .ps1.
What would change to get just the file name without the path?
What would change to get just the file name without the path?
Just replace all occurrences of 'Expression={$File.FullName}' with 'Expression={$File.Name}' (lines 16, 23, 30 in the 'batch' script above).
Open in new window
~bp