批处理 - 删除范围/特定单词



在强制下,我使用以下批处理脚本打印文件搁置/更改的列表:

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

这是我的清单.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中执行此操作,而无需执行任何脚本编写。 看看这篇博文:

https://www.perforce.com/blog/fun-formatting

您可以通过使用-e全局 opt* 运行 Perforce 消息来查看消息中的字段,如下所示:

p4 -e files ...

然后,您可以在重新格式化输出时使用任何或所有这些字段,如下所示:

p4 -F "just the filename please: %depotFile%" files ...

*另请参阅-Ztag它为您提供了输出字段的备用字典

首先,让我们看一下您的代码:

  1. 我不知道程序p4,但我认为它正在设置ErrorLevel。因此,由于此值是在您要读取的同一代码块中更新的,因此需要使用延迟扩展,因此setlocal EnableDelayedExpansion放在脚本顶部并使用!ErrorLevel!而不是%ErrorLevel%。另一种方法是用ifnot ErrorLevel 1替换if not !ErrorLevel!==0,这意味着如果ErrorLevel不大于也不等于1,或者以更简单的方式表示,如果ErrorLevel小于1,但这仅在程序不设置负值时才有效。
  2. 即使您更正了ErrorLevel问题,由于条件命令串联运算符%%if查询也永远不会执行 eb,因为这只允许以下命令在前一个命令成功的情况下执行,这意味着其退出代码1等于零。因此,要执行if语句,请使用无条件运算符&。无论如何,还有另一个条件运算符||,它允许以下命令仅在退出代码为非零值的情况下执行;这个可以完全取代你的if状况。
  3. exit命令不仅会退出批处理文件,还会终止运行批处理脚本的命令提示符 (cmd) 实例。要退出批处理文件,请改用exit /B
  4. 您正在将ErrorLevel设置为按exit -1-1。当然,您可以这样做,但通常会避免负值;因此,让我建议一个正值,例如1(按exit /B 1)。
  5. 您正在打开和关闭for循环的每个迭代的文件list.txt。这会降低整体性能。此外,如果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是相同的,但实际上在极少数情况下它们可能会有所不同。

最新更新