Creating a program called Joker.cmd (https://github.com/nightmare-dll/Joker/), and it's basically done. Was basically me testing out github at first and turned into something I wouldn't mind fully releasing.
It's basically done, so I would love to implement a user plugin system. Dir tree is as of rightnow (not synced on github);
data/
-config.cmd
plugins/
- test1.cmd
- test2.cmd
joker.cmd
So then joker.cmd would list both "test1.cmd" and "test2.cmd" and have a
set /p plugin=Plugin name;
start %plugin%.cmd
and then run the specified plugin.
The only issue is how would I get joker.cmd to list only files ending in either .cmd or .bat?
How would I get joker.cmd to list only files ending in either .cmd or .bat?
Add the following lines to joker.cmd to run the plugins automatically:
for /f "tokens=*" %%f in ('dir /b plugins\*.cmd plugins\*.bat') do (
start "" %%f
)
Add the following lines to joker.cmd to prompt for the plugin to run:
dir /b plugins\*.cmd plugins\*.bat
set /p plugin=Plugin name:
start "" plugins\%plugin%
Note:
Always include a TITLE this can be a simple string like "My Script" or just a pair of empty quotes ""
According to the Microsoft documentation, the title is optional, but depending on the other options chosen you can have problems if it is omitted.
Source start
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
dir - Display a list of files and subfolders.
for /f - Loop command against the results of another command.
start - Start a program, command or batch script (opens in a new window).
Related
I'm not great at coding in any way. I figured out that I would need to start using some code to make some tasks a lot less tiresome.
I'm currently using Plex TV which is a media server that allows you to upload TV series and movies to the online server and you can then beam it directly to a TV from a phone app. (How awesome right!)
I'm trying to upload the files, but it needs to match a certain path for it to work properly.
E.g.: TV Shows\Greys Anatomy\Season 1\Greys Anatomy - S01E01\
I've got 9 seasons worth of Greys Anatomy, but the file names are missing the hyphen: Grey's Anatomy S01E0
Is there a way to rename MULTIPLE files and insert - between Anatomy and S01E01.
I have 9 seasons without the hyphen.
I've looked at a command such as ren "Greys Anatomy "* "Greys Anatomy - "*, but it isn't working. It replaces the following S and then it screws it all up. I'm sure there is an easy solution, but I'm not good at coding and have been trying for an hour or two now.
The command syntax is: Command name ren, SPACE, argument string for file(s)/folder(s) to rename optionally with path enclosed in double quotes, SPACE, argument string for new file/folder name(s) enclosed in double quotes always without path.
So the correct command line to use would be with wildcard * inside the double quoted first and second argument strings:
ren "Grey's Anatomy *" "Greys Anatomy - *"
But this command line does not work as you want it. The number of characters in current file name up to * are 15 while the number of characters in new file name up to * are just 14. For that reason command REN takes also the next character S and renames Grey's Anatomy S01E01 with this command line to Greys Anatomy - 01E01 with S missing.
I suggest to use a batch file with following code on which the second line must be adapted by you as you have not posted full qualified path of the files to modify:
#echo off
set "SourceFolder=C:\Temp\TV Shows\Greys Anatomy"
for /F "delims=" %%I in ('dir "%SourceFolder%\Grey*Anatomy*" /A-D-H /B /S 2^>nul') do (
for /F "eol=| tokens=2*" %%A in ("%%~nxI") do ECHO ren "%%I" "Greys Anatomy - %%B"
)
set "SourceFolder="
pause
Note: There is ECHO left to command ren in fourth line to just output the rename command instead of really doing the rename. Run this batch file and verify if the output rename command lines would produce what you expect. On a positive result remove ECHO , save the batch file and run it once again to really rename the files.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?
echo /?
for /?
pause /?
ren /?
set /?
By the way: There are GUI applications like shareware file manager Total Commander which make it possible to do such file rename operations also for people with no experience in writing code using just the computer mouse.
I tried running it by passing the exact path: E:\Program files\bi\example.bat but it didn't work.
Well it should work if you get the path right.
"E:\Program files\bi\example.bat"
Program Files has a space in it. That also means it needs to be wrapped in quotes.
Pressing Ctrl + D/Ctrl + F at the command prompt will autofill. This will make sure you have the right path. From Help (cmd /?).
If completion is enabled with the /F:ON switch, the two control
characters used are Ctrl-D for directory name completion and Ctrl-F
for file name completion. To disable a particular completion
character in the registry, use the value for space (0x20) as it is not
a valid control character.
Paths should always be wrapped in double quotes " as each substring after a whitespace is seen as a new command, or switches for a command.
If you know the Path, simply enter wrapped by "
"E:\Program files\bi\example.bat"
Alternatively, the example.bat might have other switches which calls files in the directory it exists which will then be search for by the path you started cmd.exe from i.e. C:\windows\system32 which will result in a batch file that starts up, but does not work as expected. You can therefore simply cd to the path and run it if successfully changed dir.
cd "E:\Program files\bi" && example.bat
The above can be easier achieve by using your TAB key simply by starting to type the relevant Directory and then TAB which will give you the predictions of directories that exists starting with the given name.
If for instance you are not sure where the file is and considering it is the only file by this name, you can simply search for it and execute if found.
for /f "delims=" %a in ('dir /S /B /A-D example.bat') do set "variable=%a" & "%variable%"
The above line will search from the directory you run it from, but search all subfolders and once found, it will execute it. Note, should you want to run the above from a batch file, add another % to the variable %a
for /f "delims=" %%a in ('dir /S /B /A-D example.bat') do set "variable=%%a" & "%variable%"
-TheGame/
- Game files/
-> file1.whatever
-> file2.whatever
-> file3.whatever
-> Launcher.exe
-TheGameModed/
- Game files/
-> file1.whatever (the moded file)
-> Launcher.exe (the moded launcher)
I made a mod on a game and i want to create an installer for people to play my game.
In order to preventing backup problems (if the player want to revert to vanilla) i will put the mod folder aside the game folder.
The mod folder contain only the "moded files" and in want to make a batch that will copy file from the game folder that are not already present in the destination (even if there are not the same)
Is this right :
xcopy "../TheGame" "../TheGameModed" /q /s /e
There is a documentation here but i didn't find what i'm looking for :
https://www.computerhope.com/xcopyhlp.htm
I found only this :
/U Copies only files that already exist in destination.
But i need the opposite (Copies only files that doesn't exist in destination)
P.S. : When the batch copy files, it ask me if i want to overwrite or not, and since i have only few filesit is not so hard to type n few times. But the mod will be deleted if someone type y (that would be bad) and maybe next mod will contain more files :[
Perhaps ROBOCOPY can't be used because the game updating batch file should work also on Windows XP. In this case the following batch file could be perhaps used working on Windows NT4 and all later Windows versions:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0"
for /F "delims=" %%I in ('dir "TheGame\*" /A-D /B /S 2^>nul') do call :CopyFile "%%I"
popd
endlocal
exit
:CopyFile
set "SourcePath=%~dp1"
set "TargetPath=%SourcePath:\TheGame\=\TheGameModed\%"
if not exist "%TargetPath%%~nx1" %SystemRoot%\System32\xcopy.exe "%~1" "%TargetPath%" /C /I /Q >nul
goto :EOF
The batch file first creates a local environment.
Next it pushes path of current directory on stack and sets the directory of the batch file as current directory. It is expected by this batch file being stored in the directory containing the subdirectories TheGame and TheGameModed.
Then command DIR is executed to output
the names of just all files because of /A-D (attribute not directory)
with name of file only because of /B (bare format)
in specified directory TheGame and all subdirectories because of /S
and with full path also because of /S.
This DIR command line is executed in a separate command process started by FOR in background with cmd.exe /C which captures everything written by this command process respectively by DIR to handle STDOUT.
Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes DIR command line with using a separate command process started in background.
The FOR option delims= disables the standard behavior of splitting up each non empty line not starting with a semicolon into strings using space/tab as delimiter. In other words each file name with file extension and full path is assigned to loop variable I.
The name of each file with file extension and full path is passed to a subroutine called CopyFile.
The subroutine first assigns just path of source file found in TheGame directory tree to environment variable SourcePath. Next a string substitution is used to replace in this path TheGame by TheGameModed with including the directory separators on both side for more accuracy.
After having target path for current file in TheGame directory tree it is checked next if a file with that name in that path exists already in TheGameModed directory tree.
If the file does not exist, command XCOPY is used to copy this single file to TheGameModed with automatically creating the entire directory tree if that is necessary. This directory creation feature of XCOPY is the main reason for using XCOPY instead of COPY.
After processing all files in TheGame directory tree, the initial current directory is restored from stack as well as the initial environment before exiting current command process independent on calling hierarchy and how the command process was started initially.
The commands POPD and ENDLOCAL would not be really necessary with exit being the next line. I recommend usually to use exit /B or goto :EOF instead of EXIT, but goto :EOF fails if command extensions are not enabled and we can't be 100% sure that the command extensions are enabled on starting the batch file although by default command extensions are enabled on Windows.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
exit /?
goto /?
if /?
popd /?
pushd /?
set /?
setlocal /?
xcopy /?
I regularly have to rename hundreds of files across a subfolder structure. I have been creating a batch file consisting of all my rename commands, and manually pasting this into each subfolder to execute one subfolder at a time. I'd like to revise the batch script so that it executes against all subfolders in one fell swoop, run from the parent directory just once.
My renaming is very manual, and so I need to create a discrete entry for each file. For example, here are three lines:
REN STWP01_00669087* BCBSRI-01849351*
REN BCBSRI-01849357* 2011-12-19_BCBSRI-01849357*
REN STWP01_00669094* BCBSRI-01849369*
I've experimented with the FOR /R command, including trying a separate batch file that calls my renaming batch file (via the CALL command). No luck.
I have to assume that this is simple, but I'm a batch novice, so any help would be appreciated.
Thanks!
#Magoo,
Thanks so much for your response. Your approach is going to be far more efficient than my own so far.
A couple of questions. Please bear with me as I am a total novice with batch commands.
Here's what I did: I saved your code to a .BAT file ("RRename.bat"), modified my filenames as per your instructions and saved those to a text file ("Filenames.txt"), and then run this command from the command line: {RRename.bat Filenames.txt}.
The resulting command windows confirm correct renaming. And so I removed the ECHO and PAUSE commands and re-ran. No luck. Just a bunch of Command windows confirming the directory.
Ideally I'd love to save this as a .BAT file and simply drop this in the top-level directory, together with the data file that contains the old names and new names of the files. And so, a double-click of "RRename.bat" will parse the content of "Filenames.txt" and work its way through all subfolders, renaming wherever matches are encountered. Boom.
To that end:
1. How do I make it so {SET "sourcedir=} indicates the current directory (i.e. the directory in which the batch file is located)? This way I wouldn't ever need to change this variable. (I should note that I am running this script on a network location, which requires me to map the drive, resulting in a different drive letter every time.)
2. How do I hard-code the name of the data file into the script itself? My goal is an easily replicated process minimizing user input (save for the content of the data file).
3. How do I stop the individual command windows from appearing? I'll be renaming thousands of files at a time and don't want to see thousands fo corresponding command windows.
Thank you!
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
:: read parameters
SET "filename1=%~1"
SET "filename2=%~2"
IF DEFINED filename2 GOTO name
IF NOT DEFINED filename1 GOTO :EOF
:: 1 parameter - must be filename
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO START /min "ren %%a" "%~f0" %%a
GOTO :eof
:: we have 2 parameters so rename pattern 1 to pattern 2
:name
FOR /r "%sourcedir%" %%a IN ("%filename1%*") DO CALL :process "%%a"
PAUSE
GOTO :EOF
:: Process the filenames and actually do the rename
:process
:: Name of file to be changed - name and extension of %1
SET "changeme=%~nx1"
:: REPLACE up-to-from-pattern with nothing = remainder of name/extension
CALL SET "endpart=%%changeme:*%filename1%=%%"
:: and RENAME...
ECHO(REN "%~1" "%filename2%%endpart%"
GOTO :eof
You would need to change the setting of sourcedir to suit your circumstances.
Revised data file
STWP01_00669087 BCBSRI-01849351
BCBSRI-01849357 2011-12-19_BCBSRI-01849357
STWP01_00669094 BCBSRI-01849369
Aimed at processing the above file, renaming files starting (column1 entries) to start (column2 entries.)
Method:
Run the batch as
batchname filename
This will execute the batch, processing filename
How:
having set the directory name to start processing from, set filename1&2 to the values of the parameters supplied.
If only 1 is supplied, it is the filename, so process it line-by-line and START a new process /min minimised "with the window name in the first set of quotes" and execute this same batch with the data from each line of the file in turn, then finish by going to :eof (end-of-file - built-in to CMD)
The sub-processes all have 2 parameters (eg BCBSRI-01849357 2011-12-19_BCBSRI-01849357) so processing passes to :name. This runs a for /r loop, from the specified source directory, with the name specified from the first column+* and executes :process passing the filenames found as parameter 1.
:process sets changeme to the filename in question, calculates endpart by removing the string filename1 from changeme which will deliver the er, end part.
Then simply rename the supplied filename to the replacement name+that endpart calculated.
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.
The PAUSE is just to allow the proposed changes to be seen. Once the process has been verified, change the PAUSE to EXIT.
AAMOI, running
*batchname* STWP01_00669094 BCBSRI-01849369
for instance, would execute the recursive-rename from STWP01_00669094* to BCBSRI-01849369*
Sadly, "No luck" is meaningless.
I have made a minor, but significant change to the instructions. The PAUSE should be changed to an EXIT after testing.
After testing, the ECHO(... line should become
REN "%~1" "%filename2%%endpart%"
which actually executes the rename. If you've just deleted the line, it would explain the no-visible-result.
Having restored the original code and verified against a small representative dummy subtree, change the echo(... line and test again. The filenames should change. If not, something is dreadfully wrong. Needless to say, this works perfectly happily for me...
Then try again with the PAUSE changed to EXIT. This time, the windows generated will appear on the taskbar and then disappear when the rename for that line of the input file has finished. This will happen once for BCBSRI-01849357 rentwo for instance - not once for each individual file rename occurring.
To hard-code the filename, remove the line
IF NOT DEFINED filename1 GOTO :EOF
and replace
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO START /min "ren %%a" "%~f0" %%a
with
FOR /f "usebackqdelims=" %%a IN ("YOURFILENAMEHERE") DO START /min "ren %%a" "%~f0" %%a
For the "run from here" command, change
SET "sourcedir=U:\sourcedir"
to
SET "sourcedir=."
. means "the current directory"
If you place thisbatchfilename.bat into any directory on your PATH then you can run the routine simply by executing thisbatchfilename.
You can display your path by typing
path
at the prompt. PATH is the sequence of directories searched by windows to find an executable if it isn't found in the current directory. To chane path, google "change path windows" - experienced batchers create a separate directory on the path for batch files. Sometimes, they name the directory "Belfry".
Say I have a program X.EXE installed in folder c:\abcd\happy\ on the system. The folder is on the system path. Now suppose there is another program on the system that's also called X.EXE but is installed in folder c:\windows\.
Is it possible to quickly find out from the command line that if I type in X.EXE which of the two X.EXE's will get launched? (but without having to dir search or look at the process details in Task Manager).
Maybe some sort of in-built command, or some program out there that can do something like this? :
detect_program_path X.EXE
Use the where command. The first result in the list is the one that will execute.
C:\> where notepad
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe
According to this blog post, where.exe is included with Windows Server 2003 and later, so this should just work with Vista, Win 7, et al.
On Linux, the equivalent is the which command, e.g. which ssh.
As the thread mentioned in the comment, get-command in powershell can also work it out. For example, you can type get-command npm and the output is as below:
Here's a little cmd script you can copy-n-paste into a file named something like where.cmd:
#echo off
rem - search for the given file in the directories specified by the path, and display the first match
rem
rem The main ideas for this script were taken from Raymond Chen's blog:
rem
rem http://blogs.msdn.com/b/oldnewthing/archive/2005/01/20/357225.asp
rem
rem
rem - it'll be nice to at some point extend this so it won't stop on the first match. That'll
rem help diagnose situations with a conflict of some sort.
rem
setlocal
rem - search the current directory as well as those in the path
set PATHLIST=.;%PATH%
set EXTLIST=%PATHEXT%
if not "%EXTLIST%" == "" goto :extlist_ok
set EXTLIST=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
:extlist_ok
rem - first look for the file as given (not adding extensions)
for %%i in (%1) do if NOT "%%~$PATHLIST:i"=="" echo %%~$PATHLIST:i
rem - now look for the file adding extensions from the EXTLIST
for %%e in (%EXTLIST%) do #for %%i in (%1%%e) do if NOT "%%~$PATHLIST:i"=="" echo %%~$PATHLIST:i