Batch Script List Checking - list

I'm working on a Windows 7 command line batch script to automate our build process. Some of the projects that need to be built are dependent on other projects. The normal process (assuming no dependencies) is to do a dir /AD /B from the repository root directory to get the names of the projects to compile. (This works with the folder structure and naming convention we are using.) What I'd like to do is add a file, buildorder.txt, to specify any necessary build order for dependencies only, which may or may not include all of the projects that need to be built.
Here is some pseudo code to demonstrate what I'm trying to accomplish:
if exist buildorder.txt (
for /F %%i in buildorder.txt do (
rem build each project in order specified in buildorder.txt
)
)
for /F %%i in ('dir /AD /B') do (
rem build all of the remaining project that have not already been built
)
Keep in mind, some (or perhaps all of the) items discovered for the second for loop will have already been processed in the first for loop, and I would rather not build those projects a second time.
Any thoughts on how this can be accomplished would be much appreciated! Thanks!

For the second for /F loop, do
findstr /i "%%i" buildorder.txt >NUL || ( rem build %%i )
The conditional execution evaluates false and proceeds with the build if %%i is not found in buildorder.txt.

Related

Postbuild Event Copy build output to parent sibling undertermined folder

I have two solutions, WildCougarFarm and WildLionFarm both depending on a shared library
\Folder 1
\WildCougarFarm
\WildSharedLib (Separate Solution)
\Folder 2
\WildLionFarm
\WildSharedLib (Separate Solution)
When \WildSharedLib is built I want to run a post build script that automatically copies the output directories contents to the sibling \Wild[Lion|Cougar]Farm solution folder. Depending on whether WildLionFarm exists, I want it to copy with say wildHorseFarm in future.
I need an xcopy expression with a regex but xcopy doesn't support this.
Any ideas how I can accomplish this?
I figured it out.
This is pretty cool, because it uses a foreach type loop... so we ask if the parent folder of the solution contains any folders that end in farm. For any returned it will execute the xcopy statement to copy the files to that folder.
for /d %%a in ($(SolutionDir)..\*farm) do xcopy $(TargetDir)*.* "%%a\dependancies" /s /e /f /h /k /y /i

Move files based on filename with regex and delete files with lower number in a substring in the filename

I have files with the following syntax:
LWD_???_??????_???_??_??_LP?_??_?_*.PDF
Example:
LWD_ARC_G10000_102_UE_XX_LP5_08_E_Uebersicht_Bodenplatten
I want to extract substrings out of the file name and put the file into a folder with the path based on that file name like this:
C:\Lp5\ARC\G10\
First folder is the 7th part of the file name, the 2nd part is the second folder and the first 3 chars of the 3rd part is the last folder.
Then in addition to that I need an extra delete: When the files are copied to the specific folder there is a consecutively numbered part in the file name. I need the "older" files deleted so that only the "last" file is in this folder. The numbers/index is always the 30th and the 31st char.
LWD_FEU_L20000_005_IZ_00_LP8_XX_F.pdf Index 00
LWD_FEU_L20000_005_IZ_00_LP8_01_F.pdf Index 01
For now I only have a batch with static folders:
FOR /R "E:\Downloads" %%i in (LWD_ELT_A10?00_???_??_??_LP5*) do move "%%i" "C:\Lp5\ELT\A10"
FOR /R "E:\Downloads" %%i in (LWD_???_A10000_???_??_??_LP5*) do del "%%i"
...
Does anyone have an idea how to do that without VBS or sth. like that - only Windows Batch or PowerShell?
My batch strategy is as follows:
1) get list of PDF files using DIR /B
2) parse each file name into a string consisting of (pipe delimited)
file mask that matches name with ?? wildcard for positions 30,31
destination path
full file name
3) sort the strings descending, resulting in the most recent version at the top of each file name grouping.
4) process the output with FOR /F, parsing out the file mask, destination path, and full name
5) for each iteration, create the destination folder if it does not already exist, and then conditionally copy the file to the destination if there does not yet exist a file that matches the file mask.
The above strategy is non-destructive, as the original files all remain in place. You could modify step 5 to be destructive - move the newest files instead of copy, and delete the rest.
You could implement the above strategy fairly easily with pure batch. But I would use my REPL.BAT utility - a hybrid JScript/batch script that can efficiently perform sophisticated regular expression replacements. JREPL.BAT is pure script that runs natively on any Windows machine from XP onward.
The following are untested
Non-destructive version
#echo off
for /f "tokens=1,2,3 delims=|" %%A in (
'dir /b /a-d LWD_*.PDF ^| jrepl "^(LWD_(...)_(...)..._..._.._.._(LP.)_)..(_._.*\.PDF)$" "$1??$5|c:\$4\$2\$3|$&" /i /a ^| sort /r'
) do (
md "%%B" >nul 2>nul
if not exist "%%B\%%A" copy "%%C" "%%B" >nul
)
Destructive version
#echo off
for /f "tokens=1,2,3 delims=|" %%A in (
'dir /b /a-d LWD_*.PDF ^| jrepl "^(LWD_(...)_(...)..._..._.._.._(LP.)_)..(_._.*\.PDF)$" "$1??$5|c:\$4\$2\$3|$&" /i /a ^| sort /r'
) do (
md "%%B" >nul 2>nul
if not exist "%%B\%%A" (move "%%C" "%%B" >nul) else del "%%C"
)

Regular Expression in a Windows Batch File

I'm looking for way to rename multiple files with a batch job.
Yes, I know there are many Applications around which can achieve this.
But I need an automated way, something like a Batch File which I can call from a Scheduler (SOS Job Scheduler). We need to rename hundreds of files daily!
The Goal is to set the 17-25 charcaters at the beginning of the file.
00010028229720270014468393_TB-E.pdf -> 00144683930001002822972027_TB-E.pdf
000100282297202700144683931ESR-AF.pdf -> 001446839300010028229720271ESR-AF.pdf
00010031141040250016353371ESR-AF.pdf -> 00163533700010031141040251ESR-AF.pdf
0001003167580004001667217KTO.pdf -> 0016672170001003167580004KTO.pdf
Here an example which is more clearer:
0001 002822972 027 001446839 _TB-E .pdf -> 001446839 0001 002822972 027 _TB-E .pdf
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
SET "name=%%a"
CALL :transform
)
GOTO :EOF
:transform
ECHO REN "%sourcedir%\%name%" "%name:~16,9%%name:~0,16%%name:~25%"
GOTO :eof
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.
Note that the very first example you've presented has ...393_TB-E... in the transformed version, that 3 is missing.
This can be accomplished very simply with the help of REPL.BAT - a hybrid JScript/batch utility that performs a regex search and replace on each line from stdin and writes the result to stdout. The utility uses only native scripting capabilities that are available to any modern Windows machine from XP onward; no 3rd party executable required. Complete documentation is embedded within the script.
Assuming REPL.BAT is somewhere within your PATH:
#echo off
pushd "c:\sourcePath"
for /f "delims=" %%A in (
'dir /b /a-d *.pdf ^| repl "(.{16})(.{9}).*" "ren \q$&\q \q$2$1*\q" x'
) do %%A
popd
Using only native batch commands, without any CALL:
#echo off
setlocal disableDelayedExpansion
pushd "c:\sourcePath"
for /f "delims=" %%F in ('dir /b /a-d *.pdf') do (
set "file=%%F"
setlocal enableDelayedExpansion
ren "!file!" "!file:~16,9!!file:~0,17!*"
endlocal
)
popd
If you know that none of your file names contain the ! character, then you can simply enable delayed expansion at the top, and remove both SETLOCAL and ENDLOCAL from within the loop.
Both solutions above rely on the fact that * at the end of the target name will preserve the remainder of the original file name. See How does the Windows RENAME command interpret wildcards? for more info.
(\d{16})(\d+)(.*?\.pdf) -> \2\1\3
{16} means you take 16 repetitions (of a digit)

Copy list of file names from multiple directories

i'm new to the forum. I need some advice. I need help with a code to take a text file with a list of file names and copy the files from multiple folders in to one folder, but it has to end up with the most recent modified date of the file. There are hundreds of folders containing the thousands of files.
I have a batch code below to copy the files, but it does not always end up with the newest file. If there is some way to make the code below search the folders in numerical order, that would work instead of it searching in a random order. I do not care if the code i end up using is batch, vbs, or whatever.
mkdir %userprofile%\desktop\print
set FIILELIST=%userprofile%\desktop\print.txt
set FILESPATH="\\server\folder"
set DESTPATH=%userprofile%\desktop\print
for /f %%X in (%FIILELIST%) do call :COPY_FILES "%%X"
goto :eof
:COPY_FILES
for /r %FILESPATH% %%I in (%~1) do copy "%%I" "%DESTPATH%"
for /r %FILESPATH% %%I in (%~1) do Xcopy /D "%%I" "%DESTPATH%"
XCOPY /D will only copy if the destination file does not exist or if the destination file is older than the source.

Quick one; Where can I find a list of slash commands for batch scripting?

I just have a quick question for you all if you could help me I would appreciate that. I have spent this morning learning Batch scripting and while I believe I have a lot of the concepts down -- I've already started making my own functional batch scripts for my job --
I was wondering:
Is there is a list for those 'slash' commands I've been seeing while using batch scripts?
For instance:
/A = Arithmetic
/p = User Input
/D (i don't know exactly what it
stands for, but I made a script that I used to change directories a
lot quicker using cd /D C:...)
If anyone could help me find this I would appreciate it a lot. I've been finding resources with these commands kind of spread out.
Check out AllHelp : A batch script which creates a html documentation page of all batch commands. You may also download an already created page from the link.
The page contains the built-in documentation of every command, all in one page, searchable in your browser of choice.
Of course Rob van der Woude's site itself is a huge resource for everything related to batch.
As others said already, "slash" are not commands, but options (switches) of commands. Your question makes me to remember a program I used once when I was designing the switches for a Batch file I was written. This program search the output of HELP command for all commands and report in which ones a given switches was found.
#echo off
setlocal EnableDelayedExpansion
rem SeekSwitch.bat - Antonio Perez Ayala
if "%~1" neq "" if "%~1" neq /? goto begin
echo Seek for given switches in DOS commands displayed by HELP
echo/
echo SeekSwitch switch1 switch2 ...
echo/
echo/
echo Creating the COMMAND.TXT help files for all commands, if not exists
pushd "%~P0"
for /F "skip=2 delims=" %%a in ('help ^| more /T8') do (
set "line=%%a"
if "!line:~0,2!" neq " " (
for /F %%b in ("%%a") do (
if not exist "%%b.txt" (
echo Creating "%%b.txt" help file...
help %%b > "%%b.txt"
)
)
)
)
popd
goto :EOF
:begin
pushd "%~P0"
rem Insert a "\" prefix before each switch
set switches=
for %%a in (%*) do set "switches=!switches!\%%a "
rem Seek the switches in the help files
findstr /I "%switches%" *.txt
popd
For example, to know in which commands /A and /P switches are used:
SeekSwitch /A /P
When this program is executed with no parameters, it create the auxiliary files used in posterior searchs. However, HELP command just execute the given command with /? switch and there are a couple commands that does not show a help this way (like DISKPART), so you should cancel these commands in these cases, and even cancel SeekSwitch.bat itself with Ctrl-C in certain cases.
You are using the erroneous terms, don't exist generic "slashes commands", that are switches (parameters) of "X" command. for example /A and /P are parameters of SET command so all you need to do is to see the command help on console:
Set /?
The same for /D switch, wich is used by DIR and FOR commands:
Dir /?
For /?
Of course /D switch does one thing for DIR command and other thing when using it for For command, like I said, is not a generic operator/switch.
You can check the Help command on console to see a large list of avaliable commands, and each command has their help switch /?.
Here is a excellent site where you can learn all about the use of any command: http://ss64.com/nt/
And here you can learn all the things about how to use Batch syntax and operators: http://ss64.com/bash/syntax.html
Also you have Rob Van Der woude site where you can find a lot of extended code examples: http://www.robvanderwoude.com/batchfiles.php