По желанию я распечатываю список отложенных / изменений в файле с помощью следующего пакетного сценария:
for %%A IN (%ShelvedCHL%) DO (
echo Change List: %%A
p4 -p %PPort% -c %PClient% unshelve -s %%A && if NOT %ERRORLEVEL%==0 exit -1
)>> list.txt
Вот мой list.txt
Список изменений: 24536
//GSA/TOC.h#1 - unshelved, opened for edit
... /GSA/TOC.h - also opened by test@dev
... /GSA/TOC.h - also opened by test@dev
//odata/oenums.h#6 - unshelved, opened for edit
... //odata/oenums.h#6 - also opened by test@dev
Я хочу получить следующий вывод, в основном удалить предложение после - также с тире: или даже любую команду perforce, чтобы иметь меньше информации и просто список файлов:
//GSA/TOC.h#1
... /GSA/TOC.h
... /GSA/TOC.h
//odata/oenums.h#6
... //odata/oenums.h#6
Буду признателен за любую помощь, заранее спасибо!
Сначала давайте взглянем на ваш код:
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... Usually the exit code and ErrorLevel
are the same, but there are in fact some rare cases where they may differ.
Вы можете сделать это в p4
изначально, практически не выполняя никаких сценариев. Посмотрите это сообщение в блоге:
https://www.perforce.com/blog/fun-formatting
Вы можете увидеть поля в сообщении Perforce, запустив его с глобальной опцией -e
*, например:
p4 -e files ...
Затем вы можете использовать любое или все эти поля при переформатировании вывода, например:
p4 -F "just the filename please: %depotFile%" files ...
* см. также -Ztag
, который дает вам альтернативный словарь полей вывода