Batch file to convert quote-enclosed .csv to fixed width columns - batch-file

I have been tasked with getting data output from a handheld scanner into a legacy application. The scanner program does not give me any options for formatting output.
I have researched and played with this, but my DOS scripting experience is limited. I found this on your site:
Batch file convert comma delimited to fixed length
but it fails due to the quote-marks; and it does not have the capability to space fill to a desired column width.
The Input file below is what comes from the scanner. The Desired Output is what I need it to look like for the legacy application. The'|' ending each line is not desired. I used it to indicate there are trailing spaces. The output is 8 characters, a comma, then 14 characters; left justified; space filled to the right.
I have another file that has three columns 8,14,14.
Basically, I need to go from .csv to fixed width fields separated by commas.
Input:
"20009","01138913"
"20009","01138915"
"20009","01138916"
"20009","01138914"
"20009","01138918"
"20009","01138920"
"20009","01138919"
Desired output:
20009 ,01138913 |
20009 ,01138915 |
20009 ,01138916 |
20009 ,01138914 |
20009 ,01138918 |
20009 ,01138910 |
20009 ,01138919 |
Any help would be greatly appreciated.

You can use the following, which should also be robust for columns without quotation marks:
#echo off
for /f "tokens=1,2 delims=," %%x in (test.csv) do call :process %%x %%y
goto :eof
:process
set "A=%~1 "
set "B=%~2 "
set "A=%A:~0,8%"
set "B=%B:~0,14%"
(echo %A%,%B%)
There are a few tricks here. First for /f can be used to sort-of parse CSV. We get around the quotes by passing the two column values to a subroutine. As parameters can be quoted or not and we use %~1 to access them, which removes quotes if present, the quotes pose no problem here. %A% and %B% are set to the column values with lots of padding space to the right and the following two lines select the value with the appropriate padding. Then we simply output the lines one by one.
To get an output file, simply redirect into a new file, or add >> out.txt to the last line.
However, if at all you can use other tools, then by all means do so. E.g. in PowerShell this would be fairly trivial:
Parse the file
Import-Csv test.csv -Delimiter ',' -Header A,B |
Output, using a format string
ForEach-Object { '{0,-8},{1,-14}' -f $_.A,$_.B } |
Write to a new file
Out-File out.txt -Encoding Default

Related

How to remove New line character from batch variable

Good Day All!
I have a batch script, and when I echo a variable like this
echo %variable1%
I get out put like this
TestLine1
TestLine2
TestLine3
TestLine4
My goal would be to modify this variable to remove all the newline characters so the output would look more like
TestLine1TestLine2TestLine3TestLine4
Is there a simple way to do this without creating files?
Thank you for your assistance.
You can use the command tr:
cleanedVariable1=$(echo $variable1 | tr -d '\n' )
echo $cleanedVariable1
The command tr removes or translates characters. The option -d removes the given characters. In this case, we are removing all new lines from our variable and assign it to a new variable.

Batch file how to insert the text in next column?

I have an issue on inserting data into an excel sheet.
Example: I have bat file like below;
echo %computername%; %userdomain% ; %username%; %date% ; %time% >>
C:\Server\user\palani\logout.csv
This bat file returns the output like this:
ABCD-D-1256G; DIR ; viswa; Wed 09/02/2015 ; 19:17:11.85
The output below is stored in excel sheet single column.
But I want to output a separate column like this:
|ABCD-D-1256G |DIR | viswa |Wed 09/02/2015 | 19:17:11.85
Could you please guide me how to use the tab function or delimiter?
To add a new line you should add a:
& echo.
instead of the >>.
If I understand you're question right.
Your syntax is good, the only problem is the delimiter you use. check what is your List separator in your computer regional settings (control panel -> region and Language -> additionnal settings -> List separator).
Make sure your echo ouput the same thing to separate column than your computer regional settings. If your List separator is set to colon then you need to change your code to look like this:
echo %computername%,%userdomain%,%username%,%date%,%time% >> C:\Server\user\palani\logout.csv

grouping sorted list using batch file

I want to combine several files into a single one using a flat reference file. My flat file looks as follows :
master_A | SubA | SubSubA
master_A | SubA | SubSubB
master_A | SubA | SubSubC
master_A | SubB | SubSubA
master_B | SubC | SubSubA
master_B | SubC | SubSubB
...
Column B and C combined define my file location on disc and I want to use this flow to generate single files based on the grouped values of column A (the masters).
In other words, above example would result is 2 files, and the sub files would be added. So the flow would be as follows:
Generate a file called master_A.txt and add the content of SubA_SubSubA.txt, SubA_SubSubB.txt, SubA_SubSubC.txt and SubB_SubSubA.txt.
Next, generate master_B and add the content of SubC_SubSubA.txt and SubC_SubSubB.txt
And continue until end of reference file...
I didn't get much further than below to be honest...
for /F "tokens=1,2,3" %%i in (myFlatFile.txt) do (
set myMaster=%%i
set myFile=%%j_%%k.txt
rem if myMaster differs from the previous one generate a new file using myMaster
rem as filename, then add myFile content untill the master changes again.
rem What would be the best way to achieve this ?
)
#echo off
for /F "tokens=1-3 delims=| " %%i in (myFlatFile.txt) do (
type %%j_%%k.txt >> %%i.txt
)
The only problem with previous code is if the master... files may exist before the program run. In this case, a previous file delete cycle fix the problem.

Writing the same output to multiple logs

Is it possible to write the same output to more than one file in Batch?
My reason for wanting to do this is because I have a large batch script that produces a very detailed log. This is fine as it is, but i want to also output a trimmed back version of the log with a lot less detail in it. The Batch cannot be run multiple times either.
Say for instance I have a simple batch:
Echo This is a Batch Script >> Path\File1 & Path\File2
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% >> Path\File1
Appreciate any help.
Maybe you can use the tee command from Unix tools. Downloadable for free from here. Think of it like a "T" that a plumber might put in a pipe to send water two ways.
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | tee file1 file2 file3
Have a look at some examples as I am not entirely sure what your full processing requirement is, see here.
If you want to do some processing on one stream you can do this:
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | tee unfiltered.txt | FINDSTR /v "UglyStuff" > filtered.txt
Second answer, because it is different...
You could use some VBScript, like this to send your osql output to both stdout and stderr and then handle the two separately. This saves you needing to install any Unix tools.
Save this as tee.vbs
REM ############################################################################
REM File: tee.vbs
REM Author: Mark Setchell
REM I don't need any Unix purists to tell me it is not functionally idential to
REM the Unix 'tee' command, please. It does a job - that's all. And I also know
REM there is no error checking. It illustrates a technique.
REM ############################################################################
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
Set stderr = fso.GetStandardStream (2)
Do While Not WScript.StdIn.AtEndOfStream
REM Read in next line of input
Line = WScript.StdIn.ReadLine()
stdout.WriteLine(Line)
stderr.WriteLine(Line)
Loop
Then run your osql like this:
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | cscript /nologo tee.vbs 2> unfiltered.txt | FINDSTR "goodstuff" > filtered.txt
Basically, whatever the tee.vbs script writes to stderr gets redirected to wherever 2> points, and whatever tee.vbs writes to stdout goes into the FINDSTR command.
Ideally, you could put your filtering inside the tee.vbs file for maximum flexibility.

Batch file: <part of command line> was unexpected at this time

Trying to execute a command inside a batch file and drop the result into a variable.
Here's what I would execute interactively:
curl -d "username=someUser" http://someServer/trusted
The result is a 15-20 character alpha-numeric string.
Here's my attempt at doing same in a batch file:
FOR /f %AA IN('curl -d \"username=someUser\" http://someServer/trusted') DO ECHO %AA
Error returned is:
//someServer/Trusted') was unexpected at this time
I thought I was dealing with some sort of escaping issue, so I added the \ symbols in front of my quotes. From what I've read, the : symobol in http doesn't need to be escaped, but it's interesting to me that's where the failure appears to "start".
Any ideas on this? I'm on Win8.1, FYI
for-variables have one-char-variables (%A instead of %AA)
you missed a space between IN and (
in a batch-file you have to double the percent-signs for the for-variable (%%A instead of %A)
echo handles only one line, blanks brake it, you would need to pipe it maybe?

Resources