Merge Two CSV Files by Column (Rather than Inserting New Lines) - windows

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%
)
)
)

Related

CMD - Pivot / Transpose lines of file [e.g. convert 1500 lines (x1 col) --> 500 lines (x3 col)]

how please can I 'pivot' or transpose a file (i.e. turn a single-column list, into a table of data)...
Currently...
VideoA.name
VideoA.size
VideoA.bitrate
VideoB.name
VideoB.size
VideoB.bitrate
...
Desired...
VideoA.name, VideoA.size, VideoA.bitrate
VideoB.name, VideoB.size, VideoB.bitrate
Name
Size
Bitrate
VideoA.name
VideoA.size
VideoA.bitrate
VideoB.name
VideoB.size
VideoB.bitrate
Extra Info / Context
I'm aware people often ask 'why are you doing this?' so (if interested), here is the wider context / problem I am trying to solve...
I have a list of files in Files.txt
I have a jscript batch file getProps.bat that extract file properties and prints them, 1 per line
I have written a batch file to loop through Files.txt, get the properties of each and write the output to Details.csv
However if I have 500 files x 3 properties, this currently gives me 1500 lines, and I want 500 lines x 3 columns
GetProps_AllFiles.bat
---------------------
#ECHO OFF
SETLOCAL
FOR /F "tokens=*" %%A in (Files.txt) do (
getprops %%A 0,1,320 /noheaders >> Details.csv
)
Thanks in advance!
Use the "standard way" (for /f) to read a file line by line, extended by a counter. Add the line to a string (line), followed by a comma (or whatever you want to use as separator), and increase the counter. Except it's the third line. Then print the string plus the current line, reset the counter and string, and repeat.
#echo off
setlocal enabledelayedexpansion
set "line="
set count=0
(for /f "delims=" %%a in (test.txt) do (
set /a count+=1
if !count! equ 3 (
echo !line!%%a
set "line="
set count=0
) else (
set line=!line!%%a,
)
))>test.csv
The below is a slight adjustment to the code kindly provided by Stephan that allows a filename and number of lines to be passed into the script...
ColumiseFile.cmd
----------------
#ECHO OFF
SETLOCAL enabledelayedexpansion
REM :: USAGE -----------------------------------------------------------------
REM ColumiseFile [1]File.txt [2]NumOfLines
REM > Concatenates every n Lines into 1, exporting result to File.csv
SET "File=%1"
SET /A Lines=%2
REM :: MAIN -------------------------------------------------------------------
REM Thanks to Stephan [https://stackoverflow.com/a/67664755/15919675]
REM Loops through input file, compacting every n lines into 1
set "line="
set count=0
(for /f "delims=" %%a in (%File%) do (
set /a count+=1
if !count! equ %Lines% (
echo !line!%%a
set "line="
set count=0
) else (
set line=!line!%%a,
)
REM :: OUTPUT -----------------------------------------------------------------
REM Create .csv in same location as source .txt file
))>%~dpn1.csv

How to get every 3rd line of text file and put it on a separate text file using batch script

I need to get only the every 3rd line of a text file(Movie.txt) and put it on a separate text file(Title.txt) using batch script(for /f)
Movie.txt
Movie
Title
Anime1
Movie
Title
Anime2
Movie
Title
Anime3
Movie
Title
Anime4
Title.txt
Anime1
Anime2
Anime3
Anime4
currently I have no idea how to get the required data...
I would appreciate any help you can provide. thank you.
#echo off
setlocal enabledelayedexpansion
set input=yourinput.txt
set output=youroutput.txt
set i=0
for /f "tokens=*" %%l in (%input%) do (
set /a i=!i!+1
set /a r=!i!%%3
if !r!==0 echo %%l>>%output%
)
We can use the modulo operator and a line counter. !i! contains the line number and !r! is the line number modulo 3. So if !r!==0 we write the line (%%l) into the output file.
#ECHO OFF
SETLOCAL
SET "line1="
SET "line2="
FOR /f "tokens=1*delims=" %%a IN (
'findstr /r "." "100lines.txt"'
) DO (
IF DEFINED line1 (
IF DEFINED line2 (
ECHO %%a
SET "line1="
SET "line2="
) ELSE SET line2=y
) ELSE SET line1=y
)
GOTO :EOF
All you need is to replace the input filename - I have a file named 100lines.txt that contains 100 different lines of text.
Since a variable's current defined status acts on the run-time value of the variable, ensure that the two flags are clear to start, then for each line of the file,
if line1 is not defined, set it
otherwise, if line2 is not defined, set it
otherwise we are on a *3 line, so regurgitate it and clear the two flags.

how to do loop in Batch?

I want to create something like this
dup.bat infile outfile times
example usage would be
dup.bat a.txt a5.txt 5
at it would create file a5.txt that has the content of a.txt repeated 5 times
however I do not know how to do for loop in batch, how to do it?
You can do the loop like this:
SET infile=%1
SET outfile=%2
SET times=%3
FOR /L %%i IN (1,1,%times%) DO (
REM do what you need here
ECHO %infile%
ECHO %outfile%
)
Then to take the input file and repeat it, you could use MORE with redirection to append the contents of the input file to the output file. Note this assumes these are text files.
#ECHO off
SET infile=%1
SET outfile=%2
SET times=%3
IF EXIST %outfile% DEL %outfile%
FOR /L %%i IN (1,1,%times%) DO (
MORE %infile% >> %outfile%
)
For command line args
set input=%1
set output=%2
set times=%3
To do a simple for loop, read in from the input file, and write to the output file:
FOR /L %%i IN (1,1,%times%) DO (
FOR /F %%j IN (%input%) DO (
#echo %%j >> %output%
)
)
Instead of taking in an output file, you could also do it via command line:
dup.bat a.txt 5 > a5.txt
sigh
Compact Design:
SETLOCAL ENABLEDELAYEDEXPANSION
SET times=5
:Beginning
IF %times% NEQ 0 (TYPE a.txt>>a5.txt & SET /a times=%times%-1 & GOTO Beginning) ELSE ( ENDLOCAL & set times= & GOTO:eof)
Easy Reading:
SETLOCAL ENABLEDELAYEDEXPANSION
SET times=5
:Beginning
IF %times% NEQ 0 (
TYPE a.txt>>a5.txt
SET /a times=%times%-1
GOTO Beginning
) ELSE (
ENDLOCAL
set times=
GOTO:eof
)
Set your counter (times=5)
Start subroutine Beginning
If your counter doesn't equal 0, read a.txt and APPEND its contents to a5.txt, then decrement your counter by 1. This will repeat five times until your counter equals 0, then it will cleanup your variable and end the script.
SET ENABLEDELAYEDEXPANSION is important to increment variables within loops.

batch - append either date/time of creation or random to end of filename

Damsel in distress needing help with a batch-script.
I have a bunch of files that one system creates. Either in one of 2 directories, or in the directory above that.
The naming is apparently not very important, so It's a bit random.
2 questions for you batch-geniuses out there.
a) How can I append date/time of creation to the end of the filename with a batch-script?
b) How can I append a random filename (so I make the files unique) with a batch-script?
Thanks in advance, dudes and dudettes.
Yours sincerely, the Maclovin!
I have decided in my wisdom to not give a sh*t about the date of creation. I gather it follows the file anyway. What I want to do instead, is to append todays date/time to the file.
This is what I have:
SetLocal EnableDelayedExpansion
set kvitt1="c:\a"
set kvitt2="c:\b"
set tmpDir="c:\temp"
set LASTMOD=
set DATO=%DATE%
set KLOKKE=%TIME%
pause
REM lets go to this directory, and scan for files, and copy to the temp
pushd %kvitt1%
:ONE
for /f "tokens=*" %%a in ('dir /b /od 2^>NUL') do set lastmod=%%a
if "%lastmod%"=="" echo Could not locate files.&goto :TWO
COPY "%Lastmod%" %tmpDir%
pause
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
popd
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
REM Let's go to the next directory, and scan for files to copy to the temp
:TWO
REM Gå til ny nettverksstasjon
pushd %kvitt2%
for /f "tokens=*" %%a in ('dir /b /od 2^>NUL') do set lastmod=%%a
if "%lastmod%"=="" echo Could not locate files.&goto :EOF
COPY "%LASTMOD%" %tmpDir%
pause
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
popd
REM we have copied the files we need, lets skip to the temp directory for renaming and filenaming
pushd %tmpDir%
echo %tmpDir%
pause
REM this is clearly not doing much.
REM gåsetegn foran tmpDir fordi det kan finnes filer med mellomrom. dir/b lister opp filene i mappen, og lagrer det i filelist.txt
dir /b "%tmpDir%" >>filelist.txt
pause
REM går igjennom alle linjene i fillist.txt. %%i inneholder filnavnet
pause
REM for /f %%i in (filelist.txt) do
REM (
REM This is clearly not working
for /F "tokens=2,3,4 delims=/ " %%a in ('date /t') do set filedate=%%a-%%b-%%c
ren %filedate%_"%%T" "%T"
REM ren "%%T" %!random%"%%~nT.kvi")
pause
Try this for a:
ECHO Making the copy...
COPY C:\file.txt c:\file_%time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%.txt
PAUSE
CLS
EXIT
The time parsing is done by (leave out the ECHO if using it within naming a file):
ECHO %time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%
I got this from http://www.ozzu.com/mswindows-forum/can-batch-files-use-date-for-filename-creation-t75600.html where theres a bit more details about it.
As for b, the time here records up to seconds so appending the time will make it unique unless your doing more than 1 per second.
EDIT: This gets only the current date. For the batch rename to file date try this instead:
for /f "delims=|" %%f in ('dir /b C:\temp') do call :runsub %%f
goto EOF
:runsub
set t=%~t1
set t=%t::=%
set t=%t: =%
set t=%t:/=%
set renameto=%~n1-%t%%~x1
Copy %1 %renameto%
:EOF
PAUSE
You can change C:\temp to the path you want to change the files in. Let me know if theres any changes you need.
you are better off using vbscript (or powershell if you have) , rather than batch. this is because date manipulation in batch is dependent on regional settings of your computer. You will have to use tricks like going into the registry and stuff as workaround.
Here's a vbscript you can adapt to your needs.
Set objFS = CreateObject( "Scripting.FileSystemObject" )
strFolder = WScript.Arguments(0)
Set objFolder = objFS.GetFolder(strFolder)
t = Now
strDate = Year(t) & Month(t) & Day(t) & Hour(t) & Minute(t) & Second(t)
' by random number
Randomize
upperbound = 99999
lowerbound = 55555
For Each strFile In objFolder.Files
strExtension = objFS.GetExtensionName( strFile )
strName = objFS.GetBaseName( strFile)
rand = Int((upperbound - lowerbound + 1) * Rnd + lowerbound) 'gen random number
' uncomment to use date
' strFile.Name = strName & strDate & "." & strExtension
' uncomment to use random number of your choosing
' strFile.Name = strName & rand & "." & strExtension
Next

How to remove the first and last character from a file using batch script?

This is my input file content which I am using to copy to the output file.
#sdfs|dfasf|sdfs|
sdfs|df!#$%%*&!sdffs|
sasdfasfa|dfsdf|#sdfs|
What I need to do is to omit the first character '#' and last character '|' in the output file.
So the output will be,
sdfs|dfasf|sdfs|
sdfs|df!#$%%*&!sdffs|
sasdfasfa|dfsdf|#sdfs
Batch script is new to me, but I tried my best and tried these codes,
:: drop first and last char
#echo off > xyz.txt & setLocal EnableDelayedExpansion
for /f "tokens=* delims=" %%a in (E:\abc1.txt) do (
set str=%%a
set str=!str:~1!
echo !str!>> xyz.txt
)
As you can see it is not able to produce the required output.
The output now being produced is like
sdfs|dfasf|sdfs|
dfs|dfsdffs|
asdfasfa|dfsdf|#sdfs|
I don't know why the string !#$%%*&! is also getting ripped !?
Next script, call file far.vbs, anf create your new file.
Code:
set OldFile=E:\abc1.txt
set NewFile=E:\xyz.txt
echo. > "%NewFile%"
start far.vbs "%NewFile%" "%OldFile%"
far.vbs — delete first and last char from file.
Create new file far.vbs in the same folder as first script, and paste the following code:
Set OldFile = CreateObject("Scripting.FileSystemObject")
Set rdOldFile = OldFile.OpenTextFile(Wscript.Arguments(1), 1)
oContent = rdOldFile.ReadAll
rdOldFile.Close
Set lOldFile = CreateObject("Scripting.FileSystemObject")
Set lrdOldFile = OldFile.OpenTextFile(Wscript.Arguments(1), 1)
oLen = len(lrdOldFile.ReadAll)
lrdOldFile.Close
oData = oContent
oData = Right(oContent, oLen-1)
oData = Left(oData, oLen-2)
Set NewFile = CreateObject("Scripting.FileSystemObject")
Set fData = NewFile.OpenTextFile(Wscript.Arguments(0), 2)
fData.WriteLine (oData)
fData.Close
batch is never a strong point for file processing and text manipulation. If you have the luxury, you can download sed from GNU win32, then use this one liner.
C:\test>sed "/#/{s/^#//;s/|$//}" file
sdfs|dfasf|sdfs
sdfs|df!#$%%*&!sdffs|
sasdfasfa|dfsdf|#sdfs
I can't debug my code right now, but try:
:: drop first and last char
#echo off > xyz.txt
#echo off > xyz2.txt
#echo off > xyz3.txt
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (E:\abc1.txt) do (
set /a N+=1
echo %%a >> xyz.txt
echo %%b >> xyz2.txt
echo %%%c >> xyz3.txt

Resources