Change character in batch file - csv

Currently i have a csv export with the following output
number;sentence;text;text;text;text;text;text;18.05.2012;time;text;text;number
number;sentence;text;text;text;text;text;text;18.05.2012;time;text;text;number
number;sentence;text;text;text;text;text;text;#;time;text;text;number
number;sentence;text;text;text;text;text;text;#;time;text;text;number
Notice that it sometimes happens that a date is not present, instead "#" has been inserted. The # is also present in other parts of the CSV file, however this shouldn't be impacted. Which currently happens
#echo off
setlocal enableextensions enabledelayedexpansion
(for /f "skip=4 tokens=1-9* delims=," %%f in (input.csv) do if not "%%f"=="" (
set "line=%%f"
set "line=!line:#"=!"
echo(!line!
)) > output.csv
endlocal
Any pointers where i go wrong?

I guess, you didn't quite understand the "tokens" thing. The first token is set to the given variable (%%a), the next tokens are assigned to the (alphabetically) following variables (%%b, %%c, ...). You need to change the ninth token (%%i), so you have to retrieve tokens 1 to 9 and * for "the rest". Also your delimiter was wrong (your text file has ;, so you need delims=;)
#echo off
setlocal enableextensions enabledelayedexpansion
(for /f "skip=4 tokens=1-9* delims=;" %%a in (input.csv) do (
if "%%i"=="#" (set "data=") else (set "data=%%i")
echo(%%a;%%b;%%c;%%d;%%e;%%f;%%g;%%h;!data!;%%j
)) > output.csv
endlocal
(Of course you also could start with %%f, but then your ninth token is %%n - it's easier to read when you start with a)
Keep in mind, consecutive delimiters are treated as one. So if you have empty fields (...;text;;text;...) your tokenization goes wild.

Related

Batch Script - Delete Columns in csv

I do need a batch script who will remove all columns in a csv, except column 1,2 and 5
My Code:
(for /f "tokens=1,2,5 delims=;" %%i in (Input.csv) do echo %%i,%%j,%%k) > Output.csv
Input CSV
1;2;3;4;5;6;7;8;9;10
10160;"Some Name";"Something:0.8";;5;;;;;XY
Expected Output:
1;2;5
10160;"Some Name";5
Real Output
1,2,5
10160,"Some Name",XY
Does anyone have any idea why it keeps the tenth column in the second line instead of the fifth?
SETLOCAL ENABLEDELAYEDEXPANSION
(FOR /f "delims=" %%b IN (Input.csv) DO SET "line=%%b"&SET "line=!line:;;=; ;!"&for /f "tokens=1,2,5 delims=;" %%i in ("!line:;;=; ;!") do echo %%i,%%j,%%k)
The problem is that a sequence of delimiters is considered as a single delimiter, so you need to change each delimiter pair so that it contains a string, and repeat the operation for any remaining delimiter-pairs.
Obviously, you would need to take action to take care of a reported field that now contains a single space, and this will alter any quoted field that contains ;;
Note also that any data containing ! or % is likely to be corrupted and certain other symbols (such as &) may also yield unexpected results. If the data is restricted to alphamerics, spaces, commas, etc. it should be fine.

split csv by year with batch

i'm trying to split a csv file based on the year. The year is allways shown in UTC Format after first delimiter ";".
example for csv file:
ID;Datum;EUR
1;2021-12-12 12:12:12;50
1;2020-12-12 12:12:12;10
2;2020-12-12 12:12:12;20
1;2019-12-12 12:12:12;80
So far I have the following batch code as a solution.
findstr /I /R /C:"^[^;]*;2019-" "test.csv" > "test_year1.csv"
findstr /I /R /C:"^[^;]*;2020-" "test.csv" > "test_year2.csv"
findstr /I /R /C:"^[^;]*;2021-" "test.csv" > "test_year3.csv"
It works but how can i add the first line (Header) to each of this splitfiles?
Also, the code is a bit simple and unwieldy. Is it possible to automate the whole thing a bit and automatically determine the possible year's from inputfile and create a corresponding output file?
thx for help,
SaXe
#ECHO OFF
SETLOCAL
rem The following settings for the source directory, destination directory, filenames, output filename are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q71435963.txt"
:: remove variables starting #
FOR /F "delims==" %%b In ('set # 2^>Nul') DO SET "%%b="
:: set environment variables #year#yearnumber# from sourcefile
FOR /f "skip=1usebackqtokens=2delims=-;" %%b IN ("%filename1%") DO SET "#year#%%b#=Y"
:: set "line1" to first line of file
FOR /f "usebackqdelims=" %%b IN ("%filename1%") DO SET "line1=%%b"&GOTO buildfiles
:buildfiles
:: for each year found, create a new file & append data
FOR /f "tokens=2delims=#" %%b IN ('set # 2^>nul') DO (
>"%destdir%\test_%%b.csv" ECHO %line1%
>>"%destdir%\test_%%b.csv" findstr /I /R /C:"^[^;]*;%%b-" "%filename1%"
)
GOTO :EOF
The 2^>nul in each of the set commands suppresses error messages that would occur if there are no variables matching the pattern currently set. The ^ "escapes" the >, telling cmd that the > is part of the set, not of the for.
The usebackq option is only required because I chose to add quotes around the source filename.
--------- Fix for - in column 1:
in place of the for /f "skip... line, use
FOR /f "skip=1usebackqtokens=2delims=;" %%c IN ("%filename1%") DO FOR /f "delims=-" %%b IN ("%%c") DO SET "#year#%%b#=Y"
This assigns the string from the second to third occurrence of ; which grabs the second column to %%c, skipping the first line. Then the variable is set as before using the value of %%c, using - as a delimiter and selects the first token (ie. %%cup to the first delimiter) into %%b as before. The default for tokens= is tokens=1.

Remove columns from CSV Batch file

I'm trying to remove all columns in a csv file except columns 2, 3, 5, and 11
I'm having trouble with column 11.
This is my batch file:
#Echo off
(for /f "delims=" %%A in (test.csv) do Call :Split %%A
) > test_New.csv
goto :Eof
:Split
Echo(%2,%3,%5,%11
It works apart from column 11 which returns column 1.
I've tried %11% but does not work either.
Thanks
As others have already said, Batch doesn't support positional parameters greater than 9. While there are ways around that (shift /n comes to mind), a much better way of handling situations like these is to use a tokens option for for /f:
#echo off
(
for /f "tokens=2,3,5,11 delims=," %%i in (test.csv) do echo:%%i,%%j,%%k,%%l
) >"test_New.csv"
Each token causes an additional variable name to be allocated, thus the first token (#2) becomes %%i, the second (#3) %%j and so on. See for /? for further details.

For Loop in batch language

SO I have a CSV file that looks like the such:
ComputerName,UserID,192.168.0.xx
ComputerName,UserID,192.168.0.xx
I am trying to write a batch loop script that will read the IPs that are in the script and ping them this is what I have so far:
setlocal Disable DelayedExpansion
for /f "tokens=1,2,3 delims=" %%a in (test.csv) do(
Set line=%%c
ping %line%
)
Setting the variable works, but it seems like I am not able to read anything from the batch file as I am getting returned an error that says :
%%a was unexpected at this time
I was wondering how can I be able to fix that or what am I doing wrong here
There are a few issues, but you are very close. I have updated your script and noted the corrections.
REM You want to _Enable_ delayed expansion. This is a single word.
setlocal EnableDelayedExpansion
REM Your delimiter needs to be a ,
for /f "tokens=1,2,3 delims=," %%a in (test.csv) do (
Set line=%%c
REM You need to access the line value enclosed in !'s since it is delayed expansion.
ping !line!
)
Alternately, you could do this as a one-liner from the command prompt (no batch file needed):
FOR /F "tokens=1,2,3 delims=," %a in (test.csv) do PING %c
The delims= bit means that there are no delimiters and so the entire string is treated as one unbroken line instead of being split on the comma like you want. Change it to
setlocal EnableDelayedExpansion
for /f "tokens=1,2,3 delims=," %%a in (test.csv) do (
Set line=%%c
ping !line!
)

get list of files and folders to table format in CMD

I have read this thread, which helped, but doesn't answer my specific question. I'm hoping someone can help.
I am trying to export a CSV file with TWO COLUMNS of data. Column 1 is the actual filename (with extension), and Column 2 would be the immediate Folder Name (without any path info) of the file location. Question I have is, is that possible? Next question is, how can I export this as a CSV file with two columns of information?
This is a good starting point except this only has the filename (doesn't have the second column that shows the immediate folder name), and this doesn't seem to return to the next line for each filename. Instead this is simply separating with commas and not returning to new lines.
Can you advise if this is possible and offer some ideas?
#echo off
<nul (
for /f "eol=: delims=" %%F in ('dir /b /o:n') do set /p =""%%F","
) >fileList.csv
Thanks everyone!
If by the "Immediate folder name" you mean the name of the containing directory but without the path to that directory, then:
#ECHO OFF
SETLOCAL
PUSHD "%~1"
FOR /f "delims=" %%i IN ("%cd%") DO SET directory=%%~nxi
(
FOR /f "delims=" %%i IN ('dir /b /a-d /on') DO (
SETLOCAL enabledelayedexpansion
ECHO "%%i","!directory!"
endlocal
)
)>filelist.csv
POPD
The pathname of the directory required should be supplied as the first parameter, quoted if necessary.
Essentially, change to the directory in question, find and save the name of the leaf directory, then execute a directory scan returning the filenames. Quote both and output with a comma between. The inner setlocal is to allow at least some silly directory names.
edit 20130422-1421Z
#ECHO OFF
SETLOCAL
PUSHD "%~1"
FOR /f "delims=" %%i IN ("%cd%") DO SET directory=%%~nxi
(
FOR /f "delims=" %%i IN ('dir /b /a-d /on') DO (
SET fdate=%%~ti
SETLOCAL enabledelayedexpansion
ECHO "%%i","!directory!","!fdate:~0,10!"
endlocal
)
)>filelist.csv
POPD
Edited to show date as third element. Quotes retained - remove at will.
If date AND TIME are required, remove the SET fdate line and replace the "!fdate:~0,10!" with "%%~ti
Date and time format - to be certain, need to know the format you are using.
If you're doing a recursive directory search, filename with extension only can be obtained within your for /f loop from %%F by using %%~nxF. That's easy.
The trickier part is scraping the last folder from the path (%%~pF). There's actually an easy trick to that as well though. Use another for loop to get %%~nxI of %%~dpF. Yes, the filename.ext of a full path is the trailing directory.
This only works if the directory does not end in a trailing backslash, though. Since the result of %%~dpF does end in a trailing backslash, you can work around it simply by adding a single dot to the end. So instead of "c:\users\me\Desktop\" you get the ~nx of "c:\users\me\Desktop\." with a trailing dot.
Enough explanation. Here's how it's done.
#echo off
for /f "delims=" %%F in ('dir /s /b /o:n') do (
for %%I in ("%%~dpF.") do echo "%%~nxF","%%~nxI"
) >filelist.csv