Batch script issue for getting dynamic column of csv file? - windows
This is script which i am using for export the data from csv and write into a .trn extension file. The code execute for certain column of csv file data right, i mean to say if the column no indexing A to Z, code execute right,but when after the Z column means for AA,AB ect the data gets wrong. Code you can see here:
Batch Script
#echo off
set "line1=^%%a,cf,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,,,,,,,,,,,,,"
set "line2=^%%a,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,qbconid,,,^%%b,,,,,,,,,"
.......................................................................................
.......................................................................................
set "line26=^%%a,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,txtstate,,,^%%z,,,,,,,,,"
set "line27=^%%a,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,pmtper,,,^%%aa,,,,,,,,,"
set "line28=^%%a,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,minfee,^%%ab,,,,,,,,,"
(for /F "tokens=1-28 skip=1 delims=," %%a in ('type "NewPortfolios.csv"') do (
echo %line1%
echo %line2%
............
............
echo %line26%
echo %line27%
echo %line28%
)) >"file.trn"
And the csv file data is:
A B C AA AB
$portcode $qbconId $name ....... $pmtper #minfee
asingh12 123456789 Ajay Singh....... ajay 123
Output is:
asingh12,cf,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,,,,,,,,,,,,,
asingh12,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,qbconid,,,123456789,,,,,,,,,
...................................................................................
asingh12,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,pmtper,,,asingh12a,,,,,,,,,
asingh12,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,minfee,asingh12b,,,,,,,,,
In the above 2 lines you can see that the column value is coming wrong.
As you can see CSV data the last 2 column value should be ajay and 123 but it is coming as asingh12a and asingh12b.These are the values of a and b.It should come from AA and AB.
Can someone please help me in this.?
**EDITED HERE**
Hi Aacini - Hope you are doing well. I am facing again an issues with .csv file convert in to .txt file. Now this time getting a data from .csv with Quotes(") that's why the batch script is not running properly. Please find the sample data from .csv in to .txt format-
"_portcode","_qbconId","_name","_address","_city","_state","_zip","_bmeth","_ffee","_brak1","_rate0","_brak2","_rate1","_brak3","_rate2","_brak4","_rate3","_brak5","_rate4","_rate5","_bre","_custact","_custody","_qbmgrid","_refby","_txstate","_pmtper","_minfee"
"schorira","001c000000WtrL1AAJ",,"9232 Collegeview Cir","Bloomington","MN","55437","T",,"1000000.0","1.25",,,,,,,,,"1.0","Robert M. Schofield IRA Rollover",,"Schwab","JTB","Patrick Stephens","MN","Quarterly","0". Previous time in .csv data there is no Quotes. Please help me out. If you want more clarification from my side please let me know. I appreciate your help in advance.
Hi Acini,
Till now we are waiting for your reply. Please help me out.
EDIT: I fixed a couple details, it should correctly run now.
EDIT #2: Subtle bug fixed, and an example added
#echo off
set "letter=abcdefghijklmnopqrstuvwxyz"
set "line1=!a!,cf,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,,,,,,,,,,,,,"
set "line2=!a!,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,qbconid,,,!b!,,,,,,,,,"
set "line26=!a!,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,txtstate,,,!z!,,,,,,,,,"
set "line27=!a!,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,pmtper,,,!aa!,,,,,,,,,"
set "line28=!a!,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,minfee,!ab!,,,,,,,,,"
setlocal EnableDelayedExpansion
(for /F "usebackq skip=1 delims=" %%a in ("NewPortfolios.csv") do (
set i1=0
set "line=%%a"
for %%b in ("!line:,=" "!") do for /F "tokens=1,2" %%i in ("!i1! !i2!") do (
if %%i lss 26 (
set var=!letter:~%%i,1!
) else (
set var=a!letter:~%%j,1!
)
set "!var!=%%~b!
set /A i1+=1, i2=i1-26
)
echo %line1%
echo %line2%
echo %line26%
echo %line27%
echo %line28%
)) > file.trn
Previous Batch program can output up to a maximum of 52 columns (a..z aa..az), but it is very easy to increment this range. With this input data:
A, B, C, D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z, AA, AB
$portcode,$qbconId,$name, D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$pmtper,#minfee
asingh12,123456789,Ajay Singh,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,ajay,123
the output is:
asingh12,cf,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,,,,,,,,,,,,,
asingh12,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,qbconid,,,123456789,,,,,,,,,
asingh12,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,txtstate,,,Z,,,,,,,,,
asingh12,$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,pmtper,,,ajay,,,,,,,,,
asingh12,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,y,minfee,123,,,,,,,,,
Related
Remove Commas in CSV without adding extra columns
I have this script intended to remove "extra commas" within a string in a CSV. #echo off & setlocal EnableDelayedExpansion echo Removing commas from FILE CSV file... type nul > "H:\CONVERT_CSV.csv" for /F "delims=" %%i in ('type "H:\FILE.csv"') do ( set row=%%i set row=!row:"=! echo.!row!>> "H:\CONVERT_CSV.csv" ) But my script, instead of removing the comma, it adds an extra field within that record. I know the problem sits in the set row!row"=! line, but I can not figure out what. Please help Example From this: Column A,Column B Now,All,2 Then,After To this: Column A,Column B Now,All 2 Then,After EDIT: EXTRA INFO: the csv has: 123 ,the time, "Gone, For good", 2023 Then it should become: 123 ,the time, "Gone For good", 2023
Win Batch nested for returns "unexpected" error
Win10, CMD. Working on a long, complicated script, and hit a part that just does not want to cooperate. Here's a snippet that illustrates the problem: set TESTSTR="abc def ghi jkl mno pqr stu vwx yz" for /l %%a in (1,1,9) do ( set I=%%a for /f "tokens=!I!" %%b in ("%TESTSTR%") do echo %%b ) The expected result would be abc def ghi jkl mno pqr stu vwx yz But I just get 9x of this: !I!" was unexpected at this time. I've tried multiple variants of this, including set VAR="tokens=%%a" - for /f !VAR! ... I've stuck various echos in there and found that the variable %%a is incrementing properly and any intermediate vars I try to use are being set correctly. It just doesn't seem to be able to use a delayed expansion or loop variable in the options section of another loop. I've done similar pre-loop options definitions and they normally work just fine, but never tried it in nested for's, using the outside loop's variable as a parameter for the inside loop like this. Example: this code snippet works, showing only directories named "Update??" in the current dir (yes, I know that's way more than would be needed, I just grabbed it and repurposed it for this demo - the original code had a set rather than echo, with the intent of grabbing the most recent directory): set FORPARM="usebackq tokens=1" for /f %FORPARM% %%f in (`dir /b /a:d /o:d Update??`) do echo %%f This example is not inside a for or other situation that would require delayed expansion, which I think is causing issues with the problem code above - the for command just doesn't seem to be able to handle delayed expansion or for variables as part of its command. I suppose I could do it with call, putting the first for's var as a parameter to the call, and the call has the inner for, but would prefer not to - the routine I pulled this from is complex enough already - it reads a data file and populates multiple arrays. I have a variant of that routine that works, but it's pretty kludgey & requires editing when the number of arrays changes in the data file. I'm trying to speed it up, make it neater, and not require code alteration when the data alters. Anyone else ever seen and gotten past this one?
You were very close with your code. The inner for-loop needs the updated value from the outer for-loop in it's for parameter. This can be done by moving the inner for-loop to a subroutine and call this subroutine. In the code below I have changed the inner for-loop to a single-line subroutine. This keeps the code very close to yours. #echo off set TESTSTR="abc def ghi jkl mno pqr stu vwx yz" for /l %%a in (1,1,9) do ( cmd/c "#echo off&for /f "tokens=%%a" %%b in (%TESTSTR%) do echo %%b" )
I don't really consider this THE answer, but it is AN answer, based on what I was trying to avoid (and #OJBakker's answer). Putting this here instead of a comment because the comment just munges the code sections - I probably just don't know what I'm doing there yet...) With the code as: :nested_for_test set TESTSTR=abc def ghi jkl mno pqr stu vwx yz for /l %%a in (1,1,9) do ( call :nested_for_test_inner %%a ) exit /b :nested_for_test_inner for /f "tokens=%1" %%b in ("%TESTSTR%") do ( echo %%b ) exit /b Yes, I know the "do" sections do not need to be parenthecated - they are that way because the "real" code has a lot more than just a single line in each do... The results are as expected: Start: 8:28:05.98 abc def ghi jkl mno pqr stu vwx yz Start: 8:28:05.98 Stop: 8:28:07.76 Elapsed: 1.78 seconds Yes, I have a timer routine in my test file. This shows slower than I'd hoped, but within reason, considering the extra call. If someone figures out how to do it without that call, please add!
Okay... To clarify the issue. Here's the original "kludgey" code - actual code, not a simplified illustrative sample (I left my comments to explain what it's doing): :: 'call :array_load pathname [arry:val]' :: INPUT - 1-2 parameters: datafile path and optional condition :: RESULT - sets up arrays & UBOUNDs (array[0]) :: Read a datafile (identified in the first parameter). This file has an array :: definition line and a number of data lines. The array definition line starts :: with 'arry ' and lists the arrays to be populated from the data statements. :: Data statements list the information to be put into the arrays, in the same :: order as the arrays listed in the arry statement. :: An optional second parameter causes only lines that have the value given for :: that array to be included (ex: 'ZIP:23456' causes only addresses in zipcode :: 23456 to be read). :: The arry statement can be anywhere in the file. The data statements are read :: in the order of appearance. :: The Upper boundary (UBOUND) is stored in [0] :array_load set _DATAFILE=%1 set _COND=%2 if not exist %_DATAFILE% ( echo [E] - {array_load} Array datafile %1 not found. Aborting run. pause exit ) :: Detect and set up for use of the second parameter. if defined _COND for /f "tokens=1-2 delims=:" %%a in ("%_COND%") do (set _ARY=%%a&set _VAL=%%b) :: Gets the list of arrays from the "arry" statement for /f "usebackq tokens=1,*" %%a in (`findstr "^arry " %_DATAFILE%`) do ( set "ARRAYLIST=%%b") :: Set up the array names and prep for the second loop. The "tokens" var sets :: up to read the columns in the data statements. Token 1 is always "data" and :: is skipped. set ndx=1 for %%a in (%ARRAYLIST%) do ( set COL!ndx!=%%a set /a ndx+=1 ) :: "TOKENS" is not a mathematical calculation - it is a range definition used :: in the next FOR statement. Do not add /a to the set! set TOKENS=2-%ndx% set /a ARYCOUNT=ndx-1 :: Read the data statements into the arrays. The "if defined" increments the :: index for the next read only if there is no condition or the condition is :: met. The "for" inside this "if" exists because the condition can't be tested :: without it. set ndx=1 for /f "usebackq tokens=%TOKENS%" %%a in (`findstr "^data " %_DATAFILE%`) do ( set !COL1![!ndx!]=%%a if %ARYCOUNT% GEQ 2 set !COL2![!ndx!]=%%b if %ARYCOUNT% GEQ 3 set !COL3![!ndx!]=%%c if %ARYCOUNT% GEQ 4 set !COL4![!ndx!]=%%d if %ARYCOUNT% GEQ 5 set !COL5![!ndx!]=%%e if %ARYCOUNT% GEQ 6 set !COL6![!ndx!]=%%f if %ARYCOUNT% GEQ 7 set !COL7![!ndx!]=%%g if defined _COND ( for /f "usebackq" %%x in (`echo %_ARY%[!ndx!]`) do set RES=!%%x! if !RES!==%_VAL% set /a ndx+=1 ) else ( set /a ndx+=1 ) set /a !COL1![0]=!ndx!-1 if %ARYCOUNT% GEQ 2 set /a !COL2![0]=!ndx!-1 if %ARYCOUNT% GEQ 3 set /a !COL3![0]=!ndx!-1 if %ARYCOUNT% GEQ 4 set /a !COL4![0]=!ndx!-1 if %ARYCOUNT% GEQ 5 set /a !COL5![0]=!ndx!-1 if %ARYCOUNT% GEQ 6 set /a !COL6![0]=!ndx!-1 if %ARYCOUNT% GEQ 7 set /a !COL7![0]=!ndx!-1 ) exit /b This routine loads a set of index-correlated arrays. Here's an example data file. I left the comments in the file to help explain what's going on. Only the "arry" and "data" lines are actually used by the routine. To be REFERENCED by :array_load function The line starting with "arry " contains the names of the arrays to be filled from the data provided. Columns do not need to line up; extra spaces are ignored. There is a maximum of six arrays without revisiting the :array_load functions. ANY change of the "arry" names requires revisiting the code that uses them! All Data lines must begin with "data ", and NO other lines can start that way! The keywords "data" and "arry" are case-sensitive and must be followed by a space. All lines that do NOT start with "arry " or "data " are comments. arry FIRST LAST PHONE ZIP data Joe Wilson 202-417-2742 20122 data John Doe 209-659-2482 10523 data Susan Doe 209-659-2482 10523 data Bill Johnson 619-384-2582 53737 data Cindy Wahler 301-724-7496 20933 data Rebecca Tannis 410-473-2748 20536 This will result in FIRST[0]=6, FIRST[1]=Joe, LAST[0]=6, LAST[1]=Wilson, etc on up to FIRST[6]=Rebecca ... ZIP[6]=20536 (all the [0]'s = 6, as the array size) The code above works (and is reasonably fast), unless the last line is excluded by the condition check, in which case the last line is not actually excluded. It also must be edited if the number of arrays exceed the number of if ... geq .. %%... statements. I'd like to: 1) fix the last line exclusion bug, 2) remove the many IFs for array count flexibility, 3) make it faster. This is what I'm tinkering with now. It does #2, I expect it to do #1 when I get that part worked out, but it fails miserably on #3 - FAR slower. On this computer, it takes 20-30 seconds to process this list of just 6 values for only 4 arrays - my actual data files are about 110 lines with 7 values each and 21 lines of 5 each. :array_load set _DATAFILE=%1 set _FILTER= if not exist %_DATAFILE% ( echo [E] - {array_load} Array datafile %1 not found. Aborting run. pause exit /b ) if not "%2"=="" set _FILTER=%2 :: Gets the list of arrays from the "arry" statement for /f "usebackq tokens=1,*" %%a in (`findstr "^arry " %_DATAFILE%`) do ( set "ARRAYLIST=%%b") :: Set up the array names and prep for the second loop. set ndx=1 for %%a in (%ARRAYLIST%) do ( set COL[!ndx!]=%%a set /a ndx+=1 ) set /a ARYCNT=ndx-=1 :: Token 1 is always "data" and is skipped. set ndx=1 for /f "usebackq tokens=1,*" %%a in (`findstr "^data " %_DATAFILE%`) do ( set _LN=%%b for /l %%x in (1,1,%ARYCNT%) do ( set ARY=!COL[%%x]! call :array_load_inner %%x ) set /a ndx+=1 ) exit /b :array_load_inner for /f "tokens=%1" %%z in ("!_LN!") do set !ARY![!ndx!]=%%z set /a !ARY![0]=!ndx! exit /b So, does this make your eyes cross as it does mine? :) Either routine above is an "answer", just not the one I'm after - the first is my starting point, and works to the extent of the original question, which did not include references to arrays or inclusions. The second is far too slow to be viable. #Stephan answer would work if I weren't dealing with arrays. Apologies for putting this material into an "Answer" block - it's far too large for a comment (I guess I should have included original full code from the beginning, rather than try to keep the sample code at the "smallest common denominator", so to speak). Sorry...
EDIT completely changed due to new information. Please try this new code. I guess it won't get much faster using batch. As %_VAR% isn't used, you could simplify your second parameter (and skip disassembling %_COND%) #echo off setlocal enabledelayedexpansion set "file=%~1" set "_COND=%~2" if not defined file goto :eof for /f "tokens=1* delims=:" %%a in ("%_COND%") do ( set "_VAR=%%a" set "_VAL=%%b" ) rem set _ echo Start: %time% REM get field names: for /f "tokens=1*" %%A in ('findstr /b "arry " "%file%"') do ( set cnt=-1 for %%C in (%%B) do ( set /a cnt+=1 set "%%A[!cnt!]=%%C" ) ) REM get Data-Array: set "cnt=0" & REM number of data sets for /f "tokens=1*" %%A in ('findstr /brc:"data .*%_VAL%\>" %file%') do ( set /a cnt+=1 set "cnt2=-1" & REM number of entries in the dataset for %%C in (%%B) do ( set /a cnt2+=1 call set "%%arry[!cnt2!]%%[!cnt!]=%%C" call set /a %%arry[!cnt2!]%%[0]=cnt ) ) echo End: %time% set |find "[" echo there are entries 0 to %cnt%. Things that speed it up: filtering the input (less lines to process) no IF's at all works even with empty %_VAL% so no need to check it each iteration of the loop Possible contras: filterstring is case sensitive (can be changed with findstr's /i parameter, but would also make the keyword data case insensitive. Possibly false positives (John / Johnson is no probem because of the word-boundary \>, but JohnJohn would be found with the John filter (Johnjohn wouldn't)) I very much hope the 5-token datasets and the 7-token datasets are in different files There is no hardcoded limit for the tokens of the dataset. Runtimes with your example file: 200ms with filter, 260 ms without. Thanks to the filtering, a filtered list is even faster than the unfiltered.
Windows Batch script stops reading a file after a record has been written via IF in DO loop
Sometimes I think my relationship with the Windows command line is weighted in favour of Stockholms syndrome over anthing else. I'm hoping someone else in this world of punishing stuff has an answer for me! Here's the background and the problem statement: I have a quite large script that does stuff with a for loop that steps through a file searching for a record number, and changing the record while writing the records around in a nice sequential batch way, ie records are written up to the target record; a changed record is written; the remaining records are written. I needed to add a new action verb to the existing set, which requires an additional IF clause. It suddenly stopped writing out remaining records after the found record had been changed. Couldn't find the answer. So I started stripping away code until I reached this residual script. The IF clause in the FOR/ in / DO loop ... Leave it in, the script stalls after the written record as per the first sample below; leave it out, the FOR loop happily does it's thing, as per the second sample output. It gets stranger. Adding in script gives error messages, sometimes running through to completion, sometimes not ~ even a simple echo will give a parsing error. Placement in the script also seems to matter, which made debugging an absolute nightmare. Clearly there is something that is triggering the command processor to quit the loop. SO I would pose the following two questions to the community: What is causing the FOR /in /DO structure to stop processing records What gives with the echo statements giving parsing errors? (echoing a variable name with a script line number, or just the number, for instance, is very low impact. ) Thanks. Code follows, any text file can be used as the second parameter, the first is a line number to action. echo off SETLOCAL enabledelayedexpansion SET _filein=%~2 SET _line=%1 set _cnt=0 :: _filein = any file, _line = the line to be inspected, _cnt = loop counter :: in the loop: _record = line value, _msg= display message if line is found FOR /f "tokens=1 delims=" %%i IN ('type %_filein%') DO ( SET _record=%%i SET /a _cnt+=1 IF [!_cnt!]==[%_line%] ( echo the line %_line% is !_record! set _msg=the line is !_record! at position !_cnt! goto sayrecord ) echo not the line: :sayrecord echo !_cnt!- !_record! ) :Xit echo: IF [%_msg%]==[] ( echo: left out ) ELSE ( echo: I'm in to see %_msg% ) ENDLOCAL exit /b Test runs: 1. With the IF statement: (note parsing error statement) H>_a 3 _files.txt H>echo off not the line: 1- notes.bat not the line: 2- notesqa.bat the line 3 is bulkfiledelete.bat 3- bulkfiledelete.bat line was unexpected at this time. H> Without the IF: H>_a 3 _files.txt H>echo off not the line: 1- notes.bat not the line: 2- notesqa.bat not the line: 3- bulkfiledelete.bat not the line: 4- CheckAdminRights.bat not the line: : : : not the line: 47- Reset connection 3 - renew.lnk not the line: 48- ============ left out H>
OK, so I have a code block that works thanks to #jwdonaahue for the initial clue; and #SomethingDark for the problem statement. The :label is the problem here, although it works in many other production scripts it clearly is problematic. Instead of a script that drops to the bottom of the loop for processing, putting in an IF clause for each use case is what is needed. #echo off SETLOCAL enabledelayedexpansion SET _filein=%~2 SET _line=%1 set _cnt=0 :: _filein = any file, _line = the line to be inspected, _cnt = loop counter :: in the loop: _record = line value, _msg= display message if line is found FOR /f "tokens=1 delims=" %%i IN ('type %_filein%') DO ( SET _record=%%i SET /a _cnt+=1 IF [!_cnt!]==[%_line%] ( echo the line %_line% is !_record! set "_msg=the line is !_record! at position !_cnt!" echo not the line: CALL :sayrecord ) IF [!_cnt!] neq [%_line%] CALL :sayrecord ) :Xit echo: IF [%_msg%]==[] ( echo: left out ) ELSE ( echo: I'm in to see %_msg% ) ENDLOCAL exit /b :sayrecord echo !_cnt!- !_record! exit /b i.e. to solve my problem, add an IF clause for each action verb; end with an `IF' clause which wraps the records that must be written unchanged I'll also go through all the scripts and do a maint on them!
Given that your stated intent was to replace the content of %2 on line %1, you don't need delayed expansion or to set all of those variables: #For /F "Tokens=1*Delims=]" %%I In ('Type "%~2"^|"%__AppDir__%find.exe" /V /N ""')Do #If "%%I"=="[%~1%" (Echo Inserted line content)Else Echo=%%J #Pause You would modify the content after Echo and before ) to the replacement line content, and the last line is added just to ensure that you can read the output. [Edit /]If you wanted to ask the end user for confirmation of the change before doing so, you could expand your code to incorporate that: #For /F "Tokens=1*Delims=]" %%I In ('Type "%~2"^|"%__AppDir__%find.exe" /V /N ""')Do #If "%%I"=="[%~1" ("%__AppDir__%choice.exe" /M "Replace %%J with new content"&If ErrorLevel 2 (Echo=%%J)Else Echo Inserted line content)Else Echo=%%J #Pause
concatenate string in for windows command
I want to concatenate to a string in a for command but in every iteration it doesn't update the str as I would want it to do. the code is: set x=0 for %G in (1,2,3) Do set x=%x%1 the value I would like x to get is: 0111. the value accepted is: 01
I made a batch file to test this out and I got 0111 as you expected here is the batch contents: Setlocal EnableDelayedExpansion set x=0 for %%G in (1,2,3) Do set x=!x!1 echo !x! pause
Merge Two CSV Files by Column (Rather than Inserting New Lines)
I created two batch files: 1: dir *.txt %t *.* /w/a/b/-p/o:gen | find "/">rezultate.csv It gets the path and size and date and creation time of all text files from a directory and exports the result into a CSV file. 2: #echo off setlocal EnableDelayedExpansion if exist results.csv del results.csv for %%f in (D:\script\*.txt) do ( set i=0 for /F "tokens=2 delims=:" %%l in (%%f) do ( set /A i+=1 set line!i!=%%l ) echo %%f, !line1!, !line2!,>> D:\script\results.csv ) It gets the file path and what the file contains on the first 2 lines(also text files) from a specified directory and exports the result into a CSV file. I attempted to combine the batch files and I managed to export the result from both batch files into the same CSV file but the output from the first batch file is exported on the first 5 lines and the output from the second batch file is exported on the next 5 lines. I would like to merge the batch files so that the output can be exported from the first batch file wich will have one column and 5 lines and in the same CSV to export the output from the second batch file wich has 3 columns but not under the export of the first batch.I would like the CSV to have still 5 lines but 4 columns. I also attempted to merge the CSV files with another batch file but I get the same result. Please help with a solution if possible because I looked for solutions for more than one week... Here's how I need the CSV file to look: Final result will have to be like this: Thanks for your help #dohaqatar7. Here are the results that I reached today. You were right about your asumption regarding the way I would like to merge the CSV files. 1: I went for you're script for part 1 as it was more acurrate and I changed it a little bit and it will be like this: #echo off for %%a in (*.txt) do echo %%~ta,%%~za>>results.csv Sample output 2: I will remain with my script as it returns exactly what I want and it is accurate. #echo off setlocal EnableDelayedExpansion for %%f in (D:\script\*.txt) do ( set i=0 for /F "tokens=2 delims=:" %%l in (%%f) do ( set /A i+=1 set line!i!=%%l ) echo %%f, !line1!, !line2!,>>D:\script\results.csv ) sample output You have a sample also with the final result. As for the script provided to merge the CSV files I was not able to make it work as it does not return the output in a new CSV file.Could you please change it a little bit so that I can use it.I hope I explained better right now.I would have given more details but I'm new around here and I'm limited by my reputation. It would have been great if you could insert the path wich is "D:\scrip\filename\" but I can do that myself. Kind regards,
Set Arg = WScript.Arguments set WshShell = createObject("Wscript.Shell") Set Inp = WScript.Stdin Set Outp = Wscript.Stdout On Error Resume Next Set Fso = CreateObject("Scripting.FileSystemObject") Set File = Fso.OpenTextFile(Arg(1), 1, false) If err.number <> 0 then Outp.WriteLine "Error: " & err.number & " " & err.description & " from " & err.source err.clear wscript.exit End If Do Until Inp.AtEndOfStream And File.AtEndOfStream Line = "" Line2 = "" Line=Inp.readline Line2=File.readline outp.writeline Line & "," & Line2 Loop To use on screen cscript //nologo <"path to script.vbs"> "" "c:\file1.txt" < "c:\file2.txt" To put in a file cscript //nologo <"path to script.vbs"> "" "c:\file1.txt" < "c:\file2.txt" > "file3.txt"
First off, I don't know that your first piece of code does what you say it does. When I run it, the file always remains empty. This code does what you claim the first pieces does. #echo off for %%a in (*.txt) do echo %%~ta,%%~za,%%~fa If your code works for you, keep using it. If you start having issues with it, this code will work. As for combining CSV files, I am a little uncertain about what you want. Here is what I assumed. You want to take a.csv a1,b1,c1 a2,b2,c2 and b.csv d1 d2 and combine them into ab.csv a1,b1,c1,d1 a2,b2,c2,d2 This code will take two arguments, the files to combine, and output the result to a new file. #echo off setlocal enabledelayedexpansion set "line1=0" for /f "tokens=*" %%a in (%1) do ( set "file1[!line1!]=%%a" set /a line1+=1 ) set "line2=0" for /f "tokens=*" %%a in (%2) do ( set "file2[!line2!]=%%a" set /a line2+=1 ) if !line1! GTR !line2! ( set /a max=!line1!-1 ) else ( set /a max=!line2!-1 ) set "mergedCSV=%~n1_%~n2.csv" echo.>%mergedCSV% for /l %%a in (0,1,%max%) do ( if "!file1[%%a]!"=="" ( echo !file2[%%a]! >> %mergedCSV% ) else ( if "!file2[%%a]!"=="" ( echo !file1[%%a]! >> %mergedCSV% ) else ( echo !file1[%%a]!,!file2[%%a]! >> %mergedCSV% ) ) )