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

时间:2018-05-17 19:37:58

标签: batch-file perforce changelist unshelve

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

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

我希望得到任何帮助,谢谢!

2 个答案:

答案 0 :(得分:2)

您可以在p4本地执行此操作,而无需进行任何脚本编写。看看这篇博文:

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

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

p4 -e files ...

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

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

*另见-Ztag,它为您提供输出字段的备用字典

答案 1 :(得分:1)

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

  1. 我不知道程序p4,但我认为它正在设置ErrorLevel。因此,由于此值在您想要阅读的同一代码块中更新,因此您需要使用delayed expansion,因此请将setlocal EnableDelayedExpansion置于脚本之上并使用!ErrorLevel!代替%ErrorLevel%。另一种方法是将if not !ErrorLevel!==0替换为if not ErrorLevel 1,意思是,如果ErrorLevel不大于且不等于1 ,或以更简单的方式表达,如果ErrorLevel小于1 ,但仅当程序未设置负值时才有效。
  2. 即使您更正了ErrorLevel问题,if查询也永远不会因为conditional command concatenation operator %%而执行,因为这样可以执行以下命令,以防前一个命令成功,意味着它的退出代码 1 等于零。因此,要执行if语句,请使用无条件运算符&。无论如何,还有另一个条件运算符||,它允许以下命令仅在退出代码为非零值的情况下执行;这个可以完全取代if条件。
  3. exit命令不仅会退出批处理文件,还会终止批处理脚本运行的命令提示符(cmd)实例。要退出批处理文件,只能使用{{1}而不是。
  4. 您要将exit /B设置为ErrorLevel -1。当然,你可以这样做,但通常可以避免负值;因此,让我建议一个正值,如exit -11)。
  5. 您正在为for loop的每次迭代打开和关闭文件exit /B 1。这降低了整体性能。此外,如果list.txt已经存在,则数据将被追加;如果您不希望在list.txt循环之前放置del "list.txt" 2> nul以便最初删除该文件。无论如何,要一次写入整个文件,在for循环周围放置另一对括号。然后,您可以选择是使用redirection operator >>附加到现有文件,还是使用运算符for覆盖它(无需先删除它)。
  6. 所有这些都会产生以下改进的脚本:

    >

    取决于(for %%A in (%ShelvedCHL%) do ( echo Change List: %%A p4 -p %PPort% -c %PClient% unshelve -s %%A || exit /B 1 )) > "list.txt" 包含的内容(示例数据中似乎是%ShelvedCHL%,而不是文件路径/名称/掩码),24536循环甚至可能是多余的,虽然我现在还不知道......

    无论如何,以上所有内容仍未考虑删除以 SPACE + for + SPACE 开头的部分字符串,所以让我们实现现在这个:

    为了简单起见,我们可以在上面的代码之后修改文件-,使用此代码(请参阅所有解释性list.txt注释;提到的字符串操作称为sub-string substitution ):

    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

    1 ...通常退出代码和move /Y "list_NEW.txt" "list.txt" > nul 是相同的,但实际上有一些罕见的情况可能会有所不同。