0

I have a multi-line CSV that looks like this:

A/B//D
E//G/H

I am trying to use these a,b,c (blank in this case) & d as parameter inputs. The code I have today is skipping C and assign D to the 3rd position.

FOR /F " tokens=1,2,3,4 delims=/" %%i IN (MYCSV.txt"') DO tabcmd get "MyView.png?Filter1=%%A&Filter2=%%B&Filter3=%%C&Filter4=%%D" -f "Outputfile.png"

Output expected:

Mview.png?Filter1=A&Filter2=B&Filter3=&Filter4=D

What I'm getting: Mview.png?Filter1=A&Filter2=B&Filter3=D&Filter4=

Any help will be really appreciated. Thanks.

  • Welcome as a new user to SO. Please take the [tour]. If you read `help for` or visit http://ss64.com/nt/for_f.html you will recognize that this is normal behaviour, for /f ignores leading delimiters and counts successive delimiters as only one. –  Aug 09 '18 at 19:57
  • Dbenham made a nice helper batch file for this. https://www.dostips.com/forum/viewtopic.php?t=5702 – Squashman Aug 10 '18 at 03:09
  • if the change of delimters is only to be able to open it properly with Excel, [this](https://stackoverflow.com/a/42291120/2152082) might be interesting. – Stephan Aug 10 '18 at 09:05

2 Answers2

1

You could use powershell as a tool from batch which has an Import-Csv cmdlet.
It requires a temporary assignment of headers, which can be removed on saving.
The csv on output will have double quoted fileds with your choice of delimiter.

powershell -Nop -C "(Import-Csv '.\mycsv.txt' -Delim '/' -Header (1..4))|ConvertTo-Csv -NoType|Select -Skip 1|Set-Content '.\my.csv'"

Sample output:

> type my.csv
"A","B","","D"
"E","","G","H"
0

for /F combines adjacent delimiters into one for parsing text. You could however read the whole lines, temporarily insert a non-delimiter character for splitting into tokens and remove it later on, like this:

rem // Read whole lines:
for /F "usebackq delims=" %%A in ("MyCSV.txt") do (
    rem // Store current line:
    set "LINE=%%A"
    rem // Toggle delayed expansion to avoid trouble with `!`:
    setlocal EnableDelayedExpansion
    rem /* Prepend `_` to line string and replace every `/` by `/_`, hence every `/`-delimited
    rem    item becomes preceded by `_`, hence no more adjacent delimiters `/` can occur: */
    for /F "tokens=1-4 delims=/" %%a in ("_!LINE:/=/_!") do (
        endlocal
        rem // Get items preceded with `_`:
        set "ITEM1=%%a"
        set "ITEM2=%%b"
        set "ITEM3=%%c"
        set "ITEM4=%%d"
        setlocal EnableDelayedExpansion
        rem // Return rebuild line string with delimiters `,` and preceding `_` removed:
        echo(!ITEM1:~1!,!ITEM2:~1!,!ITEM3:~1!,!ITEM4:~1!
    )
    endlocal
)

Of course for just replacing the delimiter character, you could simply do this:

rem // Read whole lines:
for /F "usebackq delims=" %%A in ("MyCSV.txt") do (
    rem // Store current line:
    set "LINE=%%A"
    rem // Toggle delayed expansion to avoid trouble with `!`:
    setlocal EnableDelayedExpansion
    rem // Return new line string with delimiters replaced:
    echo(!ITEM:/=,!
    endlocal
)
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Thanks for taking the time to reply. This is helpful but isn't getting me what I want. I am looking to get those 4 values separated out so I can use them somewhere else in the process as filters. Is it possible to be able to put those values in variables that I can then use in my filters? My problem is that the 4th filter is getting applied to 3rd as the 3rd is empty string and batch file is ignoring it. – Dhruv Malik Aug 10 '18 at 15:34
  • You're welcome! I edited the first script to get the field values into separate variables; I hope it helps... – aschipfl Aug 10 '18 at 18:22
  • sorry I didn't get to see this earlier as I was travelling out of town. So, I tried your script and it does exactly what I want it to do. BUT! Now it's not recognizing my "Do Statement". Like I am using this Tabcmd to view a link and apply my filters to it, but it fails at the tabcmd piece.Maybe because I am having it do 2 things in the same For block. tabcmd get "tableauView.png?Filter1=!ITEM1:~1!&Filter2=!ITEM2:~1!&Filter3=!ITEM3:~1!&Filter4=!ITEM4:~1!" -f "\\SavedFile-!ITEM1:~1!,.png" ) endlocal ) – Dhruv Malik Aug 14 '18 at 22:31
  • Perhaps you should include the intended `tabcmd` command line in your question; at the moment I can't follow, sorry... – aschipfl Aug 15 '18 at 10:24
  • yeah i think I didn't ask the question correct. Let me rephrase the question. I'm sorry I got you confused. Thanks for helping out though. – Dhruv Malik Aug 15 '18 at 15:18
  • I still don't get what's the problem now. Could you precede the `tabcmd` command line by `echo` and check if the output is correct? – aschipfl Aug 15 '18 at 18:42
  • If I use your suggested code and insert the tabcmd code in place of the last echo, the code fails with error that tabcmd is not a recognized command. However, I have been running tabcmd in other codes within for loops. Do you think one "Do" clause in a loop can do only 1 action? And in this case it's assigning values to items. Sorry, I am very very basic when it comes to cmd. – Dhruv Malik Aug 15 '18 at 19:35
  • Okay, I don't know what `tabcmd` is, but it cannot be found, so try to specify its full path, e. g., `"C:\some\directory\tabcmd" ...`; I casn tell you this has definitely nothing to do with the `do` clause of the `for` loop... – aschipfl Aug 15 '18 at 19:49
  • okay so your solution worked. I was doing something else wrong for the tabcmd to error out. Thanks a lot for your help. Appreciate it. – Dhruv Malik Aug 16 '18 at 15:05