Reputation: 117
In perforce I print the list of shelved/changes to the file with the following batch script :
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
Here is my list.txt
Change List: 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
I want to have the following output, basically remove sentence after - with dash as well : or even any perforce command to have less information and just list of files :
//GSA/TOC.h#1
... /GSA/TOC.h
... /GSA/TOC.h
//odata/oenums.h#6
... //odata/oenums.h#6
I would appreciate any help, thanks in advance!
Upvotes: 0
Views: 339
Reputation: 71424
You can do this in p4
natively without doing hardly any scripting at all. Check out this blog post:
https://www.perforce.com/blog/fun-formatting
You can see the fields in a Perforce message by running it with the -e
global opt*, like this:
p4 -e files ...
Then you can use any or all of those fields when reformatting the output, like this:
p4 -F "just the filename please: %depotFile%" files ...
*see also -Ztag
which gives you an alternate dictionary of output fields
Upvotes: 2
Reputation: 34899
At first, let us take a look at your code:
p4
, but I assume it is setting the ErrorLevel
. So since this value is updated in the same block of code as you want to read it, you need to use delayed expansion, so place setlocal EnableDelayedExpansion
on top of your script and use !ErrorLevel!
instead of %ErrorLevel%
. Another way is to replace if not !ErrorLevel!==0
by if
not ErrorLevel 1
, meaning if ErrorLevel
is not greater than and not equal to 1
, or expressed in a simpler way, if ErrorLevel
is less than 1
, but this works only if the program does not set a negative value.ErrorLevel
issue, the if
query would never eb executed because of the conditional command concatenation operator %%
, because this lets the following command only execute in case the preceding one succeeded, meaning that its exit code1 equals zero. Therefore to execute the if
statement, use the unconditional operator &
. Anyway, there is also another conditional operator ||
, which lets the following command only execute in case the exit code is a non-zero value; this one could replace your if
condition completely.exit
command does not only quit the batch file, it also terminates the command prompt (cmd
) instance which the batch script ran in. To quit the batch file only use exit /B
instead.ErrorLevel
to -1
by exit -1
. You can do this, of course, but usually negative values are avoided; hence let me suggest a positive value like 1
(by exit /B 1
).list.txt
for every single iteration of the for
loop. This reduces overall performance. Furthermore, if list.txt
already exists, the data becomes appended; if you do not want that you need to place del "list.txt" 2> nul
before the for
loop to initially delete the file. Anyway, to write the entire file at once, put another pair of parentheses around the for
loop. You can then chose whether to append to an already existing file using the redirection operator >>
, or to overwrite it using operator >
(without any need to delete it first).All this results in the following improved script:
(for %%A in (%ShelvedCHL%) do (
echo Change List: %%A
p4 -p %PPort% -c %PClient% unshelve -s %%A || exit /B 1
)) > "list.txt"
Depending on what %ShelvedCHL%
contains (it seems to be 24536
in your sample data, so not a file path/name/mask), the for
loop might even be superfluous, although I cannot know at this point...
Anyway, all of the above does still not yet account for removal of the partial string beginning with SPACE + -
+ SPACE, so let us implement this now:
To keep it simple, we could just modify the file list.txt
after the above code, using this code (see all the explanatory rem
remarks; the mentioned string manipulation is called sub-string substitution):
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"
The resulting data is contained in the file list_NEW.txt
. To have it in the original file, append the following line to the code:
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.
Upvotes: 1