Xtrem3
Xtrem3

Reputation: 1

Create new column at each line using findstr csv file

I didn't find anything on this website about coding this feature.

Here a part of info I have and how I want it do be done. The date is always after the day data (like in my example)

Type, ID, HouseNu,TimeDepart,StartingAdress,EndingAdress, etc..
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016 12:00AM
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016 12:00AM

I want it this way

Date,Type, ID, HouseNu,TimeDepart,StartingAdress,EndingAdress, etc..
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz

Is that possible ? I know that the "12:00AM" will never appear in my data except into the datetime. So is there a possibility to find the date below the data using findstr and add a column with this date and if the date change, the date will also change?

I don't know if I am being clear enough!? Please comment if not. I appreciated the time you will give me about this problem.

FYI, the output was from an MS SQL database and i exported all the data using sqlcmd with a stored procedure. The argument was the date and i'm doing a "do while" on the storec procedure to get 4 days of data. The export give me a punch of useless information i removed using batch script. But I have no idea how to add a column using a findstr.

Here the code i'm using to get all these info:

del /q Results.csv
sqlcmd -S serveur -i C:\TA_UPS_Script\SqlScript.sql -o C:\TA_UPS_Script\Results.csv -s; -SServeur\XYZ -E
findstr /v "Changed database context to 'XYZ'." C:\TA_UPS_Script\Results.csv > C:\TA_UPS_Script\ETAPE1.csv
findstr /v "Warning"  C:\TA_UPS_Script\ETAPE1.csv > C:\TA_UPS_Script\ETAPE2.csv
findstr /v "Matricule"  C:\TA_UPS_Script\ETAPE2.csv > C:\TA_UPS_Script\ETAPE3.csv
findstr /v /c:"--------" C:\TA_UPS_Script\ETAPE3.csv > C:\TA_UPS_Script\ETAPE4.csv
del /q C:\TA_UPS_Script\ETAPE1.csv
del /q C:\TA_UPS_Script\ETAPE2.csv
del /q C:\TA_UPS_Script\ETAPE3.csv
del /q C:\TA_UPS_Script\Results.csv
type C:\TA_UPS_Script\ETAPE4.csv | repl "1899-12-30 " "" L > C:\TA_UPS_Script\ETAPE5.csv
type C:\TA_UPS_Script\ETAPE5.csv | repl ":00.000" "" L > C:\TA_UPS_Script\ETAPE6.csv
type C:\TA_UPS_Script\ETAPE6.csv | repl ".000" "" L > C:\TA_UPS_Script\ETAPE7.csv
del /q C:\TA_UPS_Script\ETAPE4.csv
del /q C:\TA_UPS_Script\ETAPE5.csv
del /q C:\TA_UPS_Script\ETAPE6.csv
type C:\TA_UPS_Script\Header.csv C:\TA_UPS_Script\ETAPE7.csv > C:\TA_UPS_Script\Results.csv
del /q C:\TA_UPS_Script\ETAPE7.csv

Upvotes: 0

Views: 235

Answers (1)

aschipfl
aschipfl

Reputation: 34979

Although you did not show any own efforts to solve your task, I decided to provide a script for that, because it does not seem quite trivial to me. So here is the code, featuring explanatory comments:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE_IN=sample.csv" & rem // (input file)
set "_FILE_OUT=con"       & rem /* (output file; must not be equal to input file!
                            rem     state `con` to output to console) */
set "_FIELD=Date" & rem // (name of prepended field to be inserted into header)
set "_SEPAR=,"    & rem // (separator character; should be the `,`)
set "$HEADER=#"   & rem /* (defines whether a header is present in the input file;
                    rem     set to empty value in case no header is there) */

rem // Redirect all data to output file once to avoid multiple file accesses:
> "%_FILE_OUT%" (
    rem // Reset index counter:
    set /A "IDX=0"
    rem // Read input file line by line:
    for /F usebackq^ delims^=^ eol^= %%L in ("%_FILE_IN%") do (
        rem // Check whether header is available:
        if defined $HEADER (
            rem // Current line is the header, so prepend new field name:
            echo(%_FIELD%%_SEPAR%%%L
            rem // Reset header flag to not treat any more lines as header:
            set "$HEADER="
        ) else (
            rem // Current line is not the header, so capture it:
            set "LINE=%%L"
            rem // Check whether current line is one of the non-CSV lines:
            setlocal EnableDelayedExpansion
            rem Avoid trouble with pipe by temporarily doubling all ":
            set "LINE=!LINE:"=""!^"
            rem Avoid trouble with pipe by temporarily escaping all %:
            set "LINE=!LINE:%%=^%%!"
            (echo "!LINE!" | > nul find "%_SEPAR%") && (
                endlocal
                rem // Current line is standard CSV line, so increment index:
                set /A "IDX+=1"
                rem /* Store current line in array-like variable `ARRAY[]`;
                rem    use `for /F` loop to overcome `endlocal` barrier: */
                setlocal EnableDelayedExpansion
                for /F "delims=" %%E in ("ARRAY[!IDX!]=!LINE!") do (
                    endlocal
                    set "%%E"
                )
            ) || (
                endlocal
                rem // Current line is non-CSV line, so extract date:
                for /F "tokens=1-3" %%I in ("%%L") do (
                    rem // The first three tokens constitute the date:
                    set "LINE=%%I %%J %%K"
                )
                rem // Return all stored CSV lines, preceded by found date:
                setlocal EnableDelayedExpansion
                for /L %%K in (1,1,!IDX!) do (
                    echo(!LINE!%_SEPAR%!ARRAY[%%K]!
                )
                endlocal
                rem // Reset index counter:
                set /A "IDX=0"
            )
        )
    )
    rem /* Return remaining stored CSV lines, preceded by an empty field,
    rem    for them not to be lost in case of a badly formatted file: */
    setlocal EnableDelayedExpansion
    for /L %%K in (1,1,!IDX!) do (
        echo(%_SEPAR%!ARRAY[%%K]!
    )
    endlocal
)

endlocal
exit /B

Basically, this batch file buffers all lines in an array-like variable ARRAY[] until a non-CSV line is encountered (such containing no ,), upon which all cached lines are output, preceded by the date portion of the non-CSV line.

This approach is supposed to be robust against all kinds of special characters appearing in the file.

Upvotes: 1

Related Questions