У меня есть многострочный CSV, который выглядит так:
A/B//D
E//G/H
Я пытаюсь использовать эти a, b, c (в данном случае пусто) и d в качестве входных параметров. Код, который у меня есть сегодня, пропускает C и назначает D на 3-ю позицию.
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"
Ожидаемый результат:
Mview.png? Filter1 = A & Filter2 = B & Filter3 = & Filter4 = D
Что я получаю: Mview.png? Filter1 = A & Filter2 = B & Filter3 = D & Filter4 =
Любая помощь будет очень признательна. Спасибо.
Dbenham сделал для этого хороший вспомогательный командный файл. dostips.com/forum/viewtopic.php?t=5702
если изменение разделителей нужно только для того, чтобы его можно было правильно открыть в Excel, это может быть интересным.
Вы можете использовать PowerShell в качестве инструмента из пакета, в котором есть командлет Import-Csv
.
Требуется временное присвоение заголовков, которые можно удалить при сохранении.
CSV на выходе будет иметь поля в двойных кавычках с выбранным вами разделителем.
powershell -Nop -C "(Import-Csv '.\mycsv.txt' -Delim '/' -Header (1..4))|ConvertTo-Csv -NoType|Select -Skip 1|Set-Content '.\my.csv'"
Пример вывода:
> type my.csv
"A","B","","D"
"E","","G","H"
for /F
объединяет соседние разделители в один для синтаксического анализа текста. Однако вы можете прочитать целые строки, временно вставить символ без разделителя для разделения на токены и удалить его позже, например:
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
)
Конечно, чтобы просто заменить символ-разделитель, вы можете просто сделать это:
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
)
Спасибо что нашли время ответить. Это полезно, но не дает мне того, чего я хочу. Я хочу отделить эти 4 значения, чтобы я мог использовать их где-нибудь еще в процессе в качестве фильтров. Можно ли поместить эти значения в переменные, которые затем можно будет использовать в своих фильтрах? Моя проблема в том, что 4-й фильтр применяется к 3-му, поскольку 3-я пустая строка, а командный файл ее игнорирует.
Пожалуйста! Я отредактировал первый скрипт, чтобы значения полей были разделены на отдельные переменные; Я надеюсь, что это помогает...
извините, я не успел увидеть это раньше, когда ехал за город. Итак, я попробовал ваш сценарий, и он делает именно то, что я хочу. НО! Теперь он не признает мое «Заявление о делах». Как будто я использую этот Tabcmd для просмотра ссылки и применения к ней моих фильтров, но он не работает в части tabcmd. Может быть, потому, что я заставляю его делать две вещи в одном блоке For. tabcmd get "tableauView.png? Filter1 =! ITEM1: ~ 1! & Filter2 =! ITEM2: ~ 1! & Filte r3 =! ITEM3: ~ 1! & Filter 4 =! ITEM4: ~ 1!" -f "\\ SavedFile-! ITEM1: ~ 1!,. png") endlocal)
Возможно, вам следует включить в свой вопрос предполагаемую командную строку tabcmd
; в данный момент я не могу следить, извините ...
да, я думаю, я не правильно задал вопрос. Позвольте мне перефразировать вопрос. Мне жаль, что я вас запутала. Тем не менее, спасибо за помощь.
Я все еще не понимаю, в чем проблема. Не могли бы вы указать tabcmd
перед командной строкой echo
и проверить правильность вывода?
Если я использую предложенный вами код и вставляю код tabcmd вместо последнего эха, код завершается ошибкой, что tabcmd не является распознанной командой. Однако я использовал tabcmd в других кодах внутри циклов for. Как вы думаете, одно предложение Do в цикле может выполнять только одно действие? И в этом случае он присваивает значения элементам. Извините, я очень прост, когда дело доходит до cmd.
Хорошо, я не знаю, что такое tabcmd
, но его невозможно найти, поэтому попробуйте указать его полный путь, например. g., "C:\some\directory\tabcmd" ...
; Я могу сказать вам, что это определенно не имеет ничего общего с предложением do
цикла for
...
хорошо, так что ваше решение сработало. Я делал что-то еще не так, чтобы tabcmd вылетел. Большое спасибо за вашу помощь. Ценить это.
Добро пожаловать в SO как новый пользователь. Пожалуйста, возьмите тур. Если вы прочитаете
help for
или посетите ss64.com/nt/for_f.html, вы поймете, что это нормальное поведение, поскольку / f игнорирует ведущие разделители и считает последовательные разделители только одним.