The goal of my overall script is to - from a central server - check individual site servers for files. If files exist, go do some work. This smaller exerpt is to aid creation of multiple entries for site names, logs, dates, and times of which I want to check the UNC path and use a variable for the site server name - the first 'token' of the UNC path. I used the example guide from Rob van der Woude's scripting page (these loops are new to me and it appears to be a basic resource) to create the FOR loop exampled below.
#echo off
SET PATH=\\UNCMainPath\SubPath1\SubPath2
FOR /F "tokens=1 delims=\" %%A IN (%PATH%) DO SET FOLDER=%%A
ECHO %FOLDER%
This is short and clean and will be easy to repeat for ~50 site servers. This code, however, does not work. The error I receive is:
The system cannot find the file \\UNCMainPath\SubPath1\SubPath2.
ECHO is off.
This, of course, tells me something is wrong before the FOR loop begins, but for the life of me I can't figure what is incorrect. Even with trash example text, I've been able to SET a variable and have it ECHO back as whatever it was set for. What have I done wrong?
Thank you to #Endoro.
Using ("%PATH%") did the trick. I forgot to enclose the variable with quotes.
Related
I want to start with a little disclaimer:
I read this thread on a similar issue to mine, but it seems like the solution doesn't work. It might just be me not understanding it completely but here I am asking for clarification.
My goal is to copy a shortcut to the start menu programs folder conserving all of its attributes, icon and start in value. I thought making a copy would be simple but it seems like my brain can't understand anything today.
So here's the actual xcopy argument:
#echo off
xcopy "%~dp0\file.lnk" "%userprofile%\Start Menu\Programs\file.lnk\" /p /v /f
pause
I have tried every combination of adding/removing the file name, with/without the \ at the end and any combination of both... I also tried running the batch file as administrator just in case.
The #echo off is just a habit and the pause is to allow me to read any error messages that could pop up. I also put the extra arguments into the xcopy line to try to get more information. It doesn't seem to help me a lot though.
I'm starting to think the issue is completely isolated from the other thread.
As suggested by SomethingDark, changing the path from %userprofile%\Start Menu\Programs\ to %AppData%\Microsoft\Windows\Start Menu\Programs\ fixed my issue.
Sorry to ask a question which will be an easy one for many of you I guess...
I'm a student in a CG School, but for the need of my project I need to code a simple .bat file to run on many computers. Everything works pretty fine, but now I need to simplify it to gain extra time setting up the .bat.
We have ALWAYS a Path like that :
D:\Project\Production\Shot\Render\Room\maya\scenes\Room_01.mb
I need two variables which store :
project : D:\Project\Production\Shot\Render\Room\maya
scene : Room_01
I think I need a loop which analyzes the path backward and sets the path after seeing 2 \ in order to avoid the file name, and the scenes folder. And I need an other thing to store all the file name ######.mb removing the .mb
I tried many things with substring forum, but it's kinda black magic for me...
So if anyone could help, I would be so grateful to you ! :)
Thank you in advance.
An easy solution is to use a for command. It will allow you to retrieve different properties of a file system reference.
set "fileReference=D:\Project\Production\Shot\Render\Room\maya\scenes\Room_01.mb"
for %%a in ("%fileReference%") do set "scene=%%~na"
Where %%~na is the name of the element being referenced by the for replaceable parameter %%a
for %%a in ("%fileReference%\..\..") do set "project=%%~fa"
Where %%~fa is the full path of the element being referenced by the for replaceable parameter %%a
A for loop is typically needed here. The first for loop grabs the last element of the string when split by a backslash. The path is then modified to have the file name removed from it, and then another for loop grabs the end off that string in the same manner.
#echo off
set my_path=D:\Project\Production\Shot\Render\Room\maya\scenes\Room_01.mb
for %%F in ("%my_path%") do set file=%%~nxF
echo.%file%
call set modded_path=%%my_path:\%file%=%%
for %%F in ("%modded_path%") do set folder=%%~nxF
echo.%folder%
I'm trying to create a batch file that can look through contents of network shares to find a specific named directory and subdirectory and then map a drive to the share that contains these. Problem being that, whilst the contents of the share have these folders in them to identify that this is the correct share, the share name itself may be different in different setups, so I can't just use the share name in the script.
In other words
\\server\share\sims\setups
the sims and setups directories will ALWAYS exist in the share, but the share name is the thing that can be different. The server name will already exist in the batch file as it is set by using the set /p command to prompt the user for the servers ip.
i have looked at the find and the forfiles commands but these seem to only work to search locally and not on network paths.
Thanks
As indicated by foxidrive you can use the net view command to list shares of a server.
The for command is able to iterate over output from commands. Combining these in the following rough commandline does map a drive for me if a certain folder/file is present.
for /F %a in ('net view \\srv') do if exist "\\srv\%a\sims\setup" net use z: \\srv\%a
(don't forget to change %a to %%a if you use this line in a command-script)
The net view does output some noise but that doesn't screw the result. You could add some extra handling to only handle shares after the '-----' line is received.
How does this work?
net view \\server outputs the following:
Shared resources at \\server
Awesome server
Share name Type Used as Comment
-----------------------------------------------------------------------------
Configuration Disk System Configuration
Download Disk Download Share (Full Access)
Public Disk Public Share (Full Access)
Blah Disk Blah share (Full Access)
The command completed successfully.
The for /f command parses each line up to the next space. From the FOR /?
FOR /F ["options"] %variable IN (`command`) DO command [command-parameters]
...you can use the FOR /F command to parse the output of a
command. You do this by making the file-set between the
parenthesis a back quoted string. It will be treated as a command
line, which is passed to a child CMD.EXE and the output is captured
into memory and parsed as if it was a file.
Using that technique would echo the following result if run on net view \\server:
Shared
Network
Share
-----------------------------------------------------------------------------
Configuration
Download
Public
Blah
The
The EXIST operator checks if a file/directory exists. By concatenating the servername, share and the expected folder you can find out if that folder does excist on that share.
As I said the first 4 lines and the last line are noise and should be ignored but they don't hurt too much in this scenario.
There's this repository which is many many gigabytes, 99% of which I don't need. What I want to do is get/update only the *.js *.css *.html .doc and *.pdf files. The rest, which are the enormous ones, I want to leave up there and not waste time and disk space getting because I don't need to look at them and I'll never be changing them.
I realize that the svn:ignore feature isn't what I need, that's related only to what gets checked in and what gets ignored. I also know that there's no parameters or settings in SVN that I can take advantage of to do what I want.
What I have found though is that if I right-click on my SVN folder and select "Check for Modifications" and then in the next dialog choose "Check repository" then I get a full list of the files I don't have. It's then an easy task to add "Extension" to the column headers and sort by extension. I can then scroll down and find all the .js files grouped together.
Here's where my #fail happens. If I right-click on ONE of the JS files and select UPDATE, then it will bring the file down and create the sub-directory hierarchy necessary to support that file. This is exactly what I'd want to happen. At this point I jump in the air thinking I've found what I need. This isn't such a troublesome process, I can live with this. Then I selected all of the JS files and right-clicked. First thing I noticed is that the context menu that appears has less options, that's troubling. But the UPDATE option is there, so I'm not too worried. I choose UPDATE then click OK, just like I did for the one single JS file I'd earlier tried. What happens next is the weird thing though. Instead of repeating the process that happened with the one single file, but this time to all selected files, it shows "Skipped" against each file and reports it's done. This happens every time. I can do each file manually (which would take hours) but I can't do them all at once.
Help. I'm doing this in a virtual machine which I'd rather not quadruple the size of just to get files I don't need.
Sorry for the delayed answer, there's been a lot going on and I also had to spend some time to get this working. As you already noted, there is no straightforward way to do an "extension-only-checkout". But there is a way using Subversion command-line tools and a batch script I wrote. It works by using the sparse directories feature of Subversion, which lets you specify which "depth" a checkout should have. By specifying a depth of empty, an empty working copy is created and no files or folders are actually checked out. Then, you can update immediate files and folders of your choice from the repository into that working copy. This allows to create that "extension-only-checkout" which you're after.
The script I wrote allows you to specify multiple extensions in the EXTENSIONS variable separated by spaces. The repository specified in the SVN_ROOT variable is then scanned for files with the given extensions. Then it proceeds to build up a working copy which consists only of the directory structure needed to support the files having the extensions you specified (using the method described above). I tested it quite a bit and hope it will suit your needs.
Note: Depending on the size of the repository and the number of files matching the specified extensions, the process of creating the working copy will take some time.
#ECHO OFF
SetLocal EnableDelayedExpansion
SET SVN_ROOT=svn://your-repository.com/svn/your-project
SET EXTENSIONS=.js .css .html .doc .pdf
SET ROOT_DIR=%CD%
ECHO Listing repository...
svn -R ls %SVN_ROOT% > _files-all.txt
REM filter list for specified extensions
FOR %%H IN (%EXTENSIONS%) DO (
TYPE _files-all.txt | FINDSTR /I /R "%%H$" >> _files-selected.txt
)
REM initial checkout in empty mode
svn co %SVN_ROOT% --depth empty .
FOR /F "tokens=*" %%I IN (_files-selected.txt) DO (
REM "escape" path elements by wrapping them into double quotes
SET TMP_PATH=%%I
SET TMP_PATH="!TMP_PATH:/=" "!"
ECHO Fetching %%I
REM iterate over path elements
FOR %%J IN (!TMP_PATH!) DO (
REM "unescape" each path element again
SET PATH_ELEM=%%J
SET PATH_ELEM=!PATH_ELEM:~1,-1!
REM if we don't have this element, fetch it from repository
IF NOT EXIST "!PATH_ELEM!" (
svn up %%J --depth empty 2>&1 > nul
)
REM if the element is a directory, enter it
IF EXIST %%~sJ\NUL CD %%J
)
CD !ROOT_DIR!
)
REM clean up temporary files
DEL _files-all.txt _files-selected.txt
I ended up having to abandon my dreams of having an svn update that only gets me certain file extensions and leaves all others on the server. I had to accept I need to get the whole thing, unless I want each update to involve navigating a large tree structure and selecting only the sub-folders I want.
I have a script who creates new tags in a SVN, and add some files. I want to automate this task so I would like to find some way to do automatically the incrementation for the tags name, from 1.0 to X.0.
I thought about a conf file who would contains "1.0" as a first version number and who would be overwrite at each call to the script. But not sure I can get the "1.0" value from the file and then do an incrementation on it in my script.
Any help would be really appreciate.
Thanks in advance
Don't create a seed configuration file. Instead, let the batch script default to 1.0 if file does not exist.
#echo off
setlocal
set "conf=version.conf"
if not exist "%conf%" (set version=1.0) else (
for /f "usebackq delims=." %%N in ("%conf%") do set /a version=%%N+1
)
set "version=%version%.0"
(echo %version%)>"%conf%"
I'm assuming you will never run this process multiple times in parallel - it can fail if you do run in parallel. Modifications can be made to lock the conf file so you can run in parallel if need be. See the accepted answer to how to check in command line if given file or directory is locked, that it is used by a process? for more info.
Take a look at keywords in Subversion using autoprops.
First, setup subversion to honor keyword expansion
enable-auto-props = yes
[auto-props]
version.txt = svn:keywords=Revision
Then, setup a simple file, let's call it version.txt with the $revision$ keyword and some random content.
$revision$
Random content
Then, in your batch file, recreate the version.txt file with new random content
echo $revision$ >version.txt
echo %random% %date% %time% >>version.txt
and check in this new file every time your batch file is run, so it will become
$revision 32 $
4214 Mon 21/01/2013 15:53:27,62
This way, subversion will keep an accurate version number of all the runs of the batch file, even in multiple clients and simultaneosly.
You might then extract and use the revision number from version.txt with code similar to
for /f "tokens=1,2" %%a in (version.txt) do (
if %%a==$revision (
echo Revision number is %%b
echo do something with %%b, create %%b tag or whatever
)
)
Since you don't say what language you want to use only general remarks can be given:
It certainly is possible to maintain a small 'version' file holding the 'dottet version number', something like 0.2.6 maybe. That files content can be read by any process. You should implement a little collection of methods to split that content into its numerical tokens (major and minor version and the like). Those numerical values can be processed by any mathematical function you like to use. For example you can increment them. Another method would be some 'implode' function that takes the numerical tokens and creates again a 'dottet version number' (now maybe 0.2.7...) and finally you can write that information back into the file. It certainly makes sense to allow an argument that controls which part of the version should be incremented.
Such scheme is not really efficient, but often sufficient.
Note, that such approach will only work if you can guarantee that it is always only a single process to access that version file. Otherwise multiple processes might overwrite each others results which certainly is a cause of problems.
As an alternative, maybe a more elegant alternative, you might consider treating the subversion repository itself as seed storage for your version number: instead of reading a special files content (what if that file is deleted or something else happens?) make a request to the tags folder inside subversion. It should contain all previously tagged versions. So that is precisely the information you want. Take all version numbers, sort them, take the highest one and process it as above.