Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   CMD/BAT ограничения for /f tokens (http://forum.oszone.net/showthread.php?t=336484)

hAh0L13 31-08-2018 09:21 2829395

CMD/BAT ограничения for /f tokens
 
Доброго времени суток

Имеется csv файл со строкой, где множество значений разделено : и | причем значений больше 60. Пишу код:

Код:

for /F "tokens=2,31 delims=:|" %%A in (!infile!) do (
if "%%A"=="foo" (
echo "%%B"))

В таком варианте выводит значения "ячейки" 31. Если изменить 31 на любое другое число больше (32, 45, и т.д.) выводится "%B".

Это что, некие ограничения CMD? Пробовал написание без кавычек с экранированием ^. То же самое.

Iska 31-08-2018 09:29 2829400

Цитата:

Цитата hAh0L13
Имеется csv файл »

Который желательно упаковать в архив и приложить к сообщению.

Цитата:

Цитата hAh0L13
Если изменить 31 на любое другое число больше (32, 45, и т.д.) выводится "%B". Это что, некие ограничения CMD? »

Это ограничение команды разбора for /f — не более 31 токена. Есть обходные пути (читайте по ссылкам в For - Loop through command output - Windows CMD - SS64.com), но я бы серьёзно задумался над иными способами, нежели пакетные файлы.

megaloman 31-08-2018 09:59 2829406

Цитата:

Цитата Iska
но я бы серьёзно задумался над иными способами, нежели пакетные файлы. »

А я бы задумался, какая конечная цель задачи, что надо поиметь в конце её решения

megaloman 31-08-2018 15:42 2829458

hAh0L13,
Если из каждой строки csv-файла с разделителями | и : надо выцепить значения с некоторыми номерами-вариант 1
Код:

@Echo Off
cls

Set "FileIn=Z:\Box_In\тра ля ля.csv"
Set "N=2 11 31 65 81"

SetLocal EnableExtensions EnableDelayedExpansion

For /F "usebackq delims=" %%s IN ("%FileIn%") DO (
        Set "SS=%%s" &Call :Delim "%%SS:|=:%%" ":" "A" "%N%"
        Echo A2=!A2!  A11=!A11!  A31=!A31!  A65=!A65!  A81=!A81!
)
Pause
GoTo :Eof

:Delim
SetLocal
        Set "S=%1"
        Call Set "S=%%S:%~2=" "%%"
        For %%j In (%~4) Do Set /A Max=%%j
EndLocal &Call :Mass %3 %4 %Max% %S%
GoTo :Eof

:Mass
        Set /A i=1
        :Begin
                For %%j In (%~2) Do If %i%==%%j Set "%~1%%j=%~4"
                Set /A i+=1
        If Not %i% GTR %3 (Shift /4 &GoTo :Begin)
GoTo :Eof

Последовательность номеров N задавайте по возрастанию
В csv файле не должно быть кавычек и всяких спецсимволов
И, очень желательно,
Цитата:

Цитата Iska
Имеется csv файл »
Который желательно упаковать в архив и приложить к сообщению. »


megaloman 31-08-2018 18:04 2829476

hAh0L13,
Если из каждой строки csv-файла с разделителями | и : надо выцепить значения с некоторыми номерами - вариант 2
Код:

@Echo Off
cls

Set "FileIn=Z:\Box_In\тра ля ля.csv"
Set "NN=2 11 31 65 81"

SetLocal EnableExtensions EnableDelayedExpansion

For %%i In (%NN%) Do Set /A Max=%%i
For /F "usebackq delims=" %%s IN ("%FileIn%") DO (
        Set "SS=%%s"
        For /L %%n In (1,1,%Max%) Do (
                For /F "tokens=1* delims=|:" %%i IN ("!SS!") DO (
                        For %%m In (%NN%) Do If %%n==%%m Set "A%%n=%%i"
                        Set "SS=%%j"
                )
        )
        Echo "A2=!A2!" "A31=!A31!"  "A11=!A11!" "A65=!A65!" "A81=!A81!"
)
pause
GoTo :Eof

Здесь возможна проблема: "вподрядные" с "ничегом" внутри разделители (|| |: |:| и т д) воспринимаются как один разделитель. В предыдущем варианте этой проблемы нет. Не проблема и здесь выкрутиться, но было лень без конкретного файла

YuS_2 31-08-2018 19:42 2829490

Начать надо с того, что файл этот совсем не csv, ибо comma-separated values...
Но даже если предположить, что это dsv, то разделитель, всё же, должен быть единым, а не:
Цитата:

Цитата hAh0L13
множество значений разделено : и | »

В общем, сначала надо определить цель задачи и привести файл в приемлемый формат, а затем уже обрабатывать его... имхо.

Iska 31-08-2018 23:34 2829503

Цитата:

Цитата YuS_2
Начать надо с того, что файл этот совсем не csv, ибо comma-separated values... »

А вдруг там что-нибудь этакое:
Код:

1,15,28,34.5,"Мама|мыла|раму:Рабы|не:мы:мы:не|рабы|Буря:мглою небо|кроет|Кот учёный",17,24
;)?

megaloman 31-08-2018 23:53 2829504

Iska,
Результат работы второго варианта скрипта на Вашего ученого сКота
Код:

1,15,28,34.5,"Мама|мыла|раму:Рабы|не:мы:мы:не|рабы|Буря:мглою небо|кроет|Кот учёный",17,24
" A1=1,15,28,34.5,"Мама"
" A2=мыла"
" A3=раму"
" A4=Рабы"
" A5=не"
" A6=мы"
" A7=мы"
" A8=не"
" A9=рабы"
"A10=Буря"
"A11=мглою небо"
"A12=кроет"
"A13=Кот учёный",17,24"

Обрамляющие кавычки приделаны в выводе Echo
То есть, эта строка обработалась правильно
Подозреваю, первый вариант на кавычках сломается.
ИМХО, второй вариант сломается на ! и еще много на чём

Iska 01-09-2018 00:14 2829506

megaloman, ну, в любом случае надо смотреть на файл. Сам автор после размещения вопроса пока не появлялся ;).

YuS_2 01-09-2018 08:11 2829512

Цитата:

Цитата Iska
А вдруг там что-нибудь этакое »

Ежели там, что-нибудь этакое и это действительный csv, то:
Цитата:

Цитата hAh0L13
множество значений разделено : и | »

- False
Всё просто... :)
Но условие задачи ведь выставил ТС, поэтому такое предположение недопустимо.
Отсюда вывод: там не csv, однако. :)

Цитата:

Цитата megaloman
Подозреваю, первый вариант на кавычках сломается.
ИМХО, второй вариант сломается на ! и еще много на чём »

имхо, здесь главное:
Цитата:

Цитата Iska
Сам автор после размещения вопроса пока не появлялся »

А что там сломается и в каком случае - дело третье. :)

DJ Mogarych 03-09-2018 10:46 2829691

А в Powershell есть отличный командлет Import-CSV, где можно указать разделитель параметром -Delimiter.
Полагаю, там будет всё сильно проще.

Iska 03-09-2018 15:48 2829722

Цитата:

Цитата DJ Mogarych
где можно указать разделитель параметром -Delimiter. »

Один разделитель, насколько я понимаю.

Автор темы сегодня появлялся, но по поводу заданных вопросов молчит, как палестинский партизан ;).


Время: 23:10.

Время: 23:10.
© OSzone.net 2001-