How do I extend this batch command? - scripting

I came across this piece of batch code. It should find the path to every single .exe file if you enter it.
#Set Which=%~$PATH:1
#if "%Which%"=="" ( echo %1 not found in path ) else ( echo %Which% )
For instance, if you save this code in the file which.bat and then go to its directory in DOS, you can write
which notepad.exe
The result will be: C:\WINDOWS\System32\notepad.exe
But it's a bit limited in that it can't find other executables. I've done a bit of batch, but I don't see how I can edit this code so that it can crawl the hard drive and return the exact path.

When you want to find an executable (or other file) anywhere on the drive, not just in PATH, then perhaps only the following will work reliably:
dir /s /b \*%!~x1 | findstr "%1"
But still, it's horribly slow. And it doesn't work with cyclic directory structures. And it probably eats children.
You may be much better off using either Windows Search (dependin on OS) or writing a program from scratch which does exactly what you want (the cyclic dir thing might happen on recent Windows versions pretty easily; afaik they have that already by default).

Here's the same thing written in python:
import os
def which(program,additional_dirs=[]):
path = os.environ["PATH"]
path_components = path.split(":")
path_components.extend(additional_dirs)
for item in path_components:
location = os.path.join(item,program)
if os.path.exists(location):
return location
return None
If called with just an argument, this will only search the path. If called with two arguments ( the second being an array ), other directories will be searched.Here are some snippets :
# this will search notepad.exe in the PATH variable
print which("notepad.exe")
# this will search whatever.exe in PATH. If not found there,
# it will continue searching in the D:\ drive and in the Program Files
print which("whatever.exe",["D:/","C:/Program Files"])

Related

Network path not working for xlswritefig in Matlab

I am trying to open a workbook that is located on a network path using the function xlswritefig. I.e. the path does not start with the traditional letter such as C:\. Instead it looks as follows:
\\networkmain\folder\to
When I try to open the excel file on this folder in Matlab, I noticed that Excel adds the current path in front of the the path. I.e. if I am currently in folder
C:\Matlab\ then Excel tries to open:
C:\Matlab\networkmain\folder\to
How can I prevent this from happening and redirect to the network path?
The problem was with the function xlswritefig. To solve for this issue, step into the function and change the following line of code (line 86):
%**op = invoke(Excel.Workbooks, 'open', [pwd filesep filename]);
op = invoke(Excel.Workbooks, 'open', filename);
Thus remove the [pwd filesep] part.
I don't think UNC paths are supported in Matlab (at least the didn't use to). The simple way forward is to map your folder to a letter drive. It is possible to do this in Windows Explorer, but I tend to use net use in the command prompt. net help use will show you the syntax
UNC (network) paths are not supported by MATLAB. However, here is a workaround which sets (and unsets) a network drive letter using the system command.
% Execute system command to assign drive letter
system('net use Z: \\networkmain\folder\to');
% Perform actions under this drive
cd(Z:\);
% ...
% Unmount the drive
system('net use Z: /delete');
You could use some simple looping to find the next available drive letter, as the system call shoudn't override an existing drive letter.

Check if Windows batch variable starts with a specific string

How can I find out (with Windows a batch command), if, for example, a variable starts with ABC?
I know that I can search for variables if I know the whole content (if "%variable%"=="abc"), but I want that it only looks after the beginning.
I also need it to find out where the batch file is located, so if there is a other command that reveals the file's location, please let me know.
Use the variable substring syntax:
IF "%variable:~0,3%"=="ABC" [...]
If you need the path to the batch file without the batch file name, you can use the variable:
%~dp0
Syntax for this is explained in the help for the for command, although this variable syntax extends beyond just the for command syntax.
to find batch file location use %0 (gives full patch to current batch file) or %CD% variable which gives local directory

How do I tell Octave where to find functions without picking up other files?

I've written an octave script, hello.m, which calls subfunc.m, and which takes a single input file, a command line argument, data.txt, which it loads with load(argv(){1}).
If I put all three files in the same directory, and call it like
./hello.m data.txt
then all is well.
But if I've got another data.txt in another directory, and I want to run my script on it, and I call
../helloscript/hello.m data.txt
this fails because hello.m can't find subfunc.m.
If I call
octave --path "../helloscript" ../helloscript/hello.m data.txt
then that seems to work fine.
The problem is that if I don't have a data.txt in the directory, then the script will pick up any data.txt that is lying around in ../helloscript.
This seems a bit fragile. Is there any way to tell octave, preferably in the script itself, to get subfunctions from the same directory as the script, but to get everything else relative to the current directory.
The best robust solution I can think of at the moment is to inline the subfunction in the script, which is a bit nasty.
Is there a good way to do this, or is it just a thorny problem that will cause occasional hard to find problems and can't be avoided?
Is this in fact just a general problem with scripting languages that I've just never noticed before? How does e.g. python deal with it?
It seems like there should be some sort of library-load-path that can be set without altering the data-load-path.
Adding all your subfunctions to your program file is not nasty at all. Why would you think so? It is perfectly normal to have function definitions in your script. The only language I know that does not do this is Matlab but that's just braindead.
The other alternative you have is to check that the input file argument, data.txt exists. Like so:
fpath = argv (){1};
[info, err, msg] = stat (fpath);
if (err)
error ("could not stat `%s' : %s", fpath, msg);
endif
## continue your script knowing the file exists
But really, I would recommend you to use both. Add your subfunctions in your main program, the only reason to have it on separate file is if you plan on sharing with other programs, and always check input arguments.

batch scripting: how to get parent dir name without full path?

I'm working on a script that processes a folder and there is always one file in it I need to rename. The new name should be the parent directory name. How do I get this in a batch file? The full path to the dir is known.
It is not very clear how the script is supposed to become acquainted with the path in question, but the following example should at least give you an idea of how to proceed:
FOR %%D IN ("%CD%") DO SET "DirName=%%~nxD"
ECHO %DirName%
This script gets the path from the CD variable and extracts the name only from it to DirName.
You can use basename command:
FULLPATH=/the/full/path/is/known
JUSTTHENAME=$(basename "$FULLPATH")
You can use built-in bash tricks:
FULLPATH=/the/full/path/is/known
JUSTTHENAME=${FULLPATH##*/}
Explanations:
first # means 'remove the pattern from the begining'
second # means 'remove the longer possible pattern'
*/ is the pattern
Using built-in bash avoid to call an external command (i.e. basename) therefore this optimises you script. However the script is less portable.

Using xcopy to copy files from several directories to one directory

Is it possible to use xcopy to copy files from several directories into one directory using only one xcopy command?
Assuming that I have the directory tree
root\Source\Sub1\Sub2
I want to copy all .xml files from the directory root\Source including sub folder to root\Destination. I don't want to copy the folder structure, just the files.
As DandDI said, you don't need xcopy. for statement helps much. However, you don't need to state process outcome of dir command as well, this command helps better
for /R c:\source %f in (*.xml) do copy "%f" x:\destination\
By the way, when you use it from a batch file, you need to add spare % in front of variable %f hence your command line should be;
for /R c:\source %%f in (*.xml) do copy %%f x:\destination\
when you use it within a batch
Should surround %f with double quotes otherwise it will fail copying file names with spaces
You don't need xcopy for that.
You can get a listing of all the files you want and perform the copy that way.
For example in windows xp command prompt:
for /f "delims==" %k in ('dir c:\source\*.xml /s /b') do copy "%k" x:\destination\
The /s goes into all subdirectories and the /b lists only the files name and path. Each file inturn is assigned to the %k variable, then the copy command copies the file to the destination. The only trick is making sure the destination is not part of the source.
The Answer to this problem which I think is "How to gather all your files out of all the little subdirectories into one single directory" is to download a piece of software called XXCOPY. This is freely available via XXCOPY.COM and there's a free non-commercial version fortunately. One of the Frequently Asked Questions on the help facility on XXCOPY.COM is effectively "How do I gather all my files into one directory" and it tells you which switch to use. XXCOPY is though a surefire way of doing this and it comes in a .zip archive so unzipping it can be not that straightforward but it's not particularly difficult either. There is an unzipping program called ZipGenius available through the ZipGenius.it website so maybe before you download XXCOPY then download ZipGenius then it's a smallpart smalltime double wammy(!)
Might not be the exact answer but if anyone would like to do this without coding.
You can search the name of the item inside a specific folder, and then you can copy the results and later paste it into your desired folder. It will rename the same file to be the folder I believe as the prefix and then the repeated name.