Сначала давайте взглянем на ваш код:
- Я не знаю программу
p4
, но я предполагаю, что она устанавливает ErrorLevel
. Так как это значение обновляется в том же блоке кода, который вы хотите прочитать, вам нужно использовать отложенное расширение , поэтому поместите setlocal EnableDelayedExpansion
поверх вашего скрипта и используйте !ErrorLevel!
вместо %ErrorLevel%
. Другой способ - заменить if not !ErrorLevel!==0
на if
not ErrorLevel 1
, что означает , если ErrorLevel
не больше и не равно 1
или выражено в более простом Кстати, , если ErrorLevel
меньше 1
, но это работает, только если программа не устанавливает отрицательное значение.
- Даже если вы исправили проблему
ErrorLevel
, запрос if
никогда не будет выполнен из-за оператора конкатенации условных команд %%
, поскольку это позволяет выполнить следующую команду только в том случае, если предыдущий преуспел, означая, что его код выхода 1 равен нулю. Поэтому для выполнения оператора if
используйте безусловный оператор &
. В любом случае, есть еще один условный оператор ||
, который позволяет выполнять следующую команду только в том случае, если код выхода имеет ненулевое значение; это может полностью заменить ваше if
состояние.
- Команда
exit
не только закрывает пакетный файл, но и завершает экземпляр командной строки (cmd
), в котором запускался пакетный сценарий. Чтобы выйти из пакетного файла, используйте только exit /B
.
- Вы устанавливаете
ErrorLevel
на -1
с помощью exit -1
. Вы можете сделать это, конечно, но обычно избегают отрицательных значений; поэтому позвольте мне предложить положительное значение, например 1
(exit /B 1
).
- Вы открываете и закрываете файл
list.txt
для каждой итерации цикла for
. Это снижает общую производительность. Кроме того, если list.txt
уже существует, данные добавляются; если вы не хотите, чтобы для удаления файла вам нужно было поместить del "list.txt" 2> nul
перед циклом for
. В любом случае, чтобы записать весь файл одновременно, поместите еще одну пару скобок вокруг цикла for
. Затем вы можете выбрать, добавлять ли файл в уже существующий файл с помощью оператора перенаправления >>
или перезаписывать его с помощью оператора >
(без необходимости сначала удалять его).
Все это приводит к следующему улучшенному сценарию:
(for %%A in (%ShelvedCHL%) do (
echo Change List: %%A
p4 -p %PPort% -c %PClient% unshelve -s %%A || exit /B 1
)) > "list.txt"
В зависимости от того, что %ShelvedCHL%
содержит (кажется, 24536
в ваших примерах данных, а не пути к файлу / имени / маске), цикл for
может быть даже излишним, хотя я не могу знать в этом точка ...
В любом случае, все вышеперечисленное еще не учитывает удаление частичной строки, начинающейся с SPACE + -
+ SPACE , поэтому давайте реализуем это сейчас:
Для простоты мы могли бы просто изменить файл list.txt
после кода выше, используя этот код (см. Все пояснительные замечания rem
; упомянутое манипулирование строками называется подстановка подстрок ):
rem // Read file `list.txt` line by line:
(for /F "usebackq delims= eol=|" %%L in ("list.txt") do (
rem // Assign line string to variable:
set "LINE=%%L"
rem // Enable delayed expansion to be able to do string manipulation:
setlocal EnableDelayedExpansion
rem /* Replace every occurrence of ` - ` by a single character `|`, then use this one
rem as a delimiter to split the line string as `for /F` requires single-character
rem delimiters; just using `-` is not good as they might occur in the partial
rem strings that need to be kept, I suppose; the `|` must not occur in them: */
for /F "tokens=1 delims=| eol=|" %%K in ("!LINE: - =|!") do (
rem // Disable delayed expansion to not lose `!`-marks:
endlocal
rem // Return the split string, that is the part before the (first) ` - `:
echo %%K
)
)) > "list_NEW.txt"
Полученные данные содержатся в файле list_NEW.txt
. Чтобы иметь его в исходном файле, добавьте следующую строку к коду:
move /Y "list_NEW.txt" "list.txt" > nul
1 ... Обычно код выхода и ErrorLevel
совпадают, но на самом деле в некоторых редких случаях они могут различаться.