Как в пакетном файле обрабатывать символ «)» на входе цикла for?

Мне нужно перебрать каждое слово в строке текста и получить последнее слово.

Для этого я использую следующий код.

for %%a in (%_IFLE_input%) do ( set _IFLE_last_token=%%a )

_IFLE_last_token= теперь содержит последнее слово.

Однако я просто нажал слово, содержащее символ ), и это остановило скрипт с ошибкой.

Close) was unexpected at this time.

Текст был Left)Close

Я попытался поместить входную переменную в кавычки

for %%a in ("%_IFLE_input%") do ( set _IFLE_last_token=%%a )

Но тогда %%a — это просто вся строка, пробелы и все такое.

Есть ли правильный способ заключить строку в кавычки, чтобы for проходил каждое слово, но не нарушая синтаксис цикла for для таких символов, как )?

Единственный вариант, который я вижу, - это отфильтровать все ядовитые символы, а затем разбить их на пробелы.

Есть ли лучший способ, в пакетном режиме? (Или с помощью внешних инструментов, доступных для необновленной Windows 10 22h2)

PowerShell входит в стандартную комплектацию компьютеров под управлением Windows и может делать все, что вы хотите, без проблем, связанных с отсутствием в cmd различия между данными и кодом.

mojo 26.04.2024 13:51

Да, powershell будет для /f "usebackq tokens=*" %%a в (powershell -command "'%_IFLE_input%'.Split(' ')[-1]") do set _IFLE_last_token=%%a, но я хочу сделать это в чистом пакете

Shodan 03.05.2024 01:53

Ну, вы сказали: «Или с помощью внешних инструментов, доступных для необновленной Windows 10 22h2», в которую входит PowerShell. Ваши требования полностью определяются вами.

mojo 08.05.2024 14:51

Вы правы, powershell — один из них. Я спросил неточно. Я имел в виду такие инструменты, как findstr, fc или certutil. Вещи, которые все еще могут работать на dos 6.22 или win95.

Shodan 08.05.2024 21:14

вы действительно ожидаете, что findstr.exe или certutil.exe будут существовать в DOS или Win95? Если вам нужна максимальная (теоретическая) совместимость, возможно, вам следует установить планку XP или 2000. Что-нибудь до этого, и вы даже не можете ожидать, что cmd.exe будет вести себя так же.

mojo 30.05.2024 15:33

Вы правы, я попробовал Win95 cmd, и даже длинные имена меток, которые я использую, не работают. Мне интересно, можно ли перенести cmd.exe и другие .exe из w2k обратно в win9x. Я видел, как кто-то заставлял dotnet работать на Win95, так что, возможно, это возможно. Но да, таргетинг на w2k более разумен. Я также предпочитаю использовать скрипт в чистом пакете. Я нахожу их менее пугающими для совместного использования, чем powershell, плюс вероятность того, что групповые политики будут останавливать выполнение пакетных файлов, меньше, чем powershell, на компьютерах только для пользователей.

Shodan 04.06.2024 22:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Другой способ обработки проблемной строки — отложенное расширение (переменная расширяется после анализа строки, что предотвращает синтаксическую ошибку.

@echo off
setlocal enabledelayedexpansion
set "var=Left)Close"
for %%a in (!var!) do ( set "last=%%a" )
set last

Примечание: таким образом могут возникнуть проблемы, если строка содержит один или несколько !.

Когда вы говорите о «каждой строке текстового файла»:

@echo off
setlocal enabledelayedexpansion
set "var=Left!Close"
for /f "delims = " %%x in (test.txt) do (
  for %%a in (%%x) do ( set "last=%%a" )
  echo !last!
)

Спасибо, это работает. Я считаю, что это «стандартный» ответ, и принимаю его. Однако ответ @squashman более впечатляющий. Жаль, что я не могу принять оба с комментариями

Shodan 02.05.2024 02:15
SET "last=%%~a"

Этот неуклюжий синтаксис позволяет (пытаться) запретить cmd.exe обрабатывать данные в %%a как код. ~ удаляет окружающие кавычки из %%a, что является гарантией при использовании кавычек для защиты содержимого переменной.

Даже это не защитит вас от всех специальных символов постоянно. cmd.exe имеет некоторые серьезные ограничения при обработке текста и строк, и это одно из них.

Вот метод, который использует подстановку строк для присвоения первого и последнего слова переменным. При необходимости код можно расширить, чтобы присвоить каждое слово массиву переменных.

@echo off & setlocal
rem http://www.dostips.com/forum/viewtopic.php?f=3&t=6429

set "_IFLE_input=A long sentence) with lots of word(s) and stuff!"
set "_IFLE_first_token=%_IFLE_input:  = " & set "_IFLE_last_token=%"
echo First word: %_IFLE_first_token%
echo Last word: %_IFLE_last_token%

endlocal

Выход

D:\My Drive\BatchFiles\SO\78389129>so.bat
First word: A
Last word: stuff!

Другой вариант — заключить каждый термин, разделенный пробелами, в кавычки.

@echo off & setlocal

set "_IFLE_input=A long sentence) with lots of word(s) and stuff!"
for %%G in ("%_IFLE_input:  = " "%") do ( set _IFLE_last_token=%%~G )
echo Last word: %_IFLE_last_token%
endlocal

Выход

D:\My Drive\BatchFiles\SO\78389129>so3.bat
Last word: stuff!

Спасибо, что указали на это. Это волшебство все еще выше моей зарплаты! Но я подтверждаю, что все работает отлично! Интересно, смогу ли я построить из них правильные функции объединения и разделения!

Shodan 02.05.2024 02:14

Есть ли у сообщества программистов пакетных файлов название для этого метода?

Shodan 03.05.2024 00:13

@Shodan это базовая замена строк.

Squashman 03.05.2024 03:31

Я имею в виду, что это нечто большее: при подмене выполняется внедрение команд. %_IFLE_input: = " и установите "_IFLE_last_token=%

Shodan 03.05.2024 06:08

Я имею в виду следующее, в частности %_IFLE_input: = " & set "_IFLE_last_token=%

Shodan 10.05.2024 02:41

Другие вопросы по теме