Windows 10 Batch File - IF Usage - windows

I have a simple batch file that contains a single line:
if not exist "C:\users\fred\desktop\b\" ( md "C:\users\fred\desktop\b" ) &&copy /Y "C:\users\fred\desktop\b.txt" "C:\users\fred\desktop\b\"
You can see the intent - if a particular folder doesn't exist on the desktop, create it. Regardless of whether the folder already existed, copy a particular file into that folder.
Note that there are two commands on the same line - the IF conditional and the copy command, using the "&&" operator.
But when I execute it, it only ever works if the folder doesn't exist. Then it creates the folder and copies the file to it. If the folder already exists, then it does nothing. It's like it thinks the whole thing is in the IF condition, regardless of the '(' and ')' around the folder creation.
I would swear that this worked on earlier versions of Windows...but I could be wrong.
FWIW, Windows 10 32 bit.

The code you post did not work in previous Windows versions either.
As written, your code says if this folder does not exist, make the directory and copy the file. If the directory exists, it never gets to the copy the file part.
What you want is for the copy to work regardless of whether the directory had to be created or not, so you need to use two separate lines.
if not exist "C:\users\fred\desktop\b\" md "C:\users\fred\desktop\b"
copy /Y "C:\users\fred\desktop\b.txt" "C:\users\fred\desktop\b\"

As suggested in the comments by CatCat, how about using XCopy instead?
With a trailing backslash on the destination, it will be created if it doesn't already exist.
Example:
Xcopy "%UserProfile%\Desktop\b.txt" "%UserProfile%\Desktop\b\" /H /K /Q /R /Y
You can adjust the options as necessary, enter XCopy /? for the usage information.

The then-part of an if command extends to the end of the line and may include several commands separated by &, && or ||. This has been so since the days of Windows NT, when cmd.exe was first introduced.
To restrict the then-part and keep the script on one single line you can place the if in a parenthesized compound command:
( if not exist "C:\users\fred\desktop\b\" md "C:\users\fred\desktop\b" ) & copy /y "C:\users\fred\desktop\b.txt" "C:\users\fred\desktop\b\"
( if not exist "directory" md "directory" )
By placing the if in a parenthesized compound command we ensure that the then-part does not extend to the end of the line
&
Command separator.
copy /y "file" "directory"
Executed regardless of the exit status of the previous command.

Related

Trying to batch merge 2 .jpeg's horizontally and put them in a different folder after

this is for my doctoral thesis in medicine. So please excuse my noobishnis in programing.
I have a bunch (about 4000 files) of scans from patients. There is a front and a back .jpg for each patient. And there where multiple patients each day.
The folder structure looks like this:
\images
\2017-08-21
\pa_102165.jpg
\pa_10216500001.jpg
\2017-06-14
\pa_101545.jpg
\pa_10154500001.jpg
\pa_104761.jpg
\pa_10476100001.jpg
\pa_107514.jpg
\pa_10751400001.jpg
\2017-03-73
\pa_109631.jpg
\pa_10963100001.jpg
\pa_108624.jpg
\pa_10862400001.jpg
Where in the first example 2017-08-21 is the date the patient came in, pa_102165.jpg is the front and pa_10216500001.jpg is the back. So the front is always pa_10XXXX.jpg and the back is pa_10XXXX00001.jpg. I had no hand in the nameing scheme.
My goal is to make a batchscript that merges the 2 corresponding .jpgs of each patient horizontally and automatically puts them in a different folder, so that I don't have to do it manually with something like MS Paint.
For example like this:
\images
\merged
\2017-08-21
\pa_102165_merged.jpg
\2017-06-14
\pa_101545_merged.jpg
\pa_104761_merged.jpg
\pa_107514_merged.jpg
\2017-03-73
\pa_109631_merged.jpg
\pa_108624_merged.jpg
I'm working on Windows 10 and found two promising methods so far but fail to comprehend how to make this into a batch file or something like it.
IrfanView Thumbnails
1. Mark the 2 corresponding .jpgs
2. File>Create contact sheet from selected files...
3. Create
4. File>Save as... in destination folder which i have to create for every day
which is faster than merging them by hand but would consume multiple workdays to do for all the pairs
and...
ImageMagic in Windows cmd
C:\Users\me\doctor\Images\test\images\2016-03-31>convert pa_102165.jpg pa_10216500001.jpg +append pa_102165_merged.jpg
This produces the merged .jpeg in the same folder the input images are in. This looks more promising but I fail to grasp how I could automate this process given the nameing scheme and the folder structure.
Thanks for taking the time to read this! I'm happy for every input you have!
This should get you fairly close. Essentially it is using the power of the FOR command modifiers to extract the base file name and file extension. The FOR /F command is capturing the output of the DIR command that is piped to the FINDSTR command. We are doing that so we only grab files with the file mask of pa_######.jpg
Once we have that we use the command modifiers with the IF command to make sure the 00001 file exists. If it does exist then it will execute the convert command. For the sake of making sure the code is performing correctly I am just ECHOING the output to the screen. If the output on the screen looks correct then remove the ECHO so that the CONVERT command executes.
#echo off
CD /D "C:\Users\me\doctor\Images\test\images"
FOR /F "delims=" %%G IN ('DIR /A-D /B /S PA_*.jpg ^|findstr /RIC:"pa_[0-9][0-9][0-9][0-9][0-9][0-9]\.jpg$"') DO (
IF EXIST "%%~dpnG00001%%~xG" (
ECHO convert "%%G" "%%~dpnG00001%%~xG" +append "%%~dpnG_merged%%~xG"
)
)
This task could be done with IrfanView with the following batch file stored in the directory containing the folder images.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IrfanView=%ProgramFiles(x86)%\IrfanView\i_view32.exe"
set "SourcePath=%~dp0images"
set "TargetPath=%~dp0merged"
for /F "delims=" %%I in ('%SystemRoot%\System32\where.exe /R "%SourcePath%" pa_10????.jpg 2^>nul') do for %%J in ("%%~dpI.") do (
if not exist "%TargetPath%\%%~nxJ\%%~nI_merged%%~xI" if exist "%%~dpnI00001%%~xI" (
if not exist "%TargetPath%\%%~nxJ\" md "%TargetPath%\%%~nxJ"
if exist "%TargetPath%\%%~nxJ\" (
echo Merging "%%~nxJ\%%~nxI" and "%%~nxJ\%%~nI00001%%~xI" ...
"%IrfanView%" /convert="%TargetPath%\%%~nxJ\%%~nI_merged%%~xI" /jpgq=95 /panorama=(1,"%%I","%%~dpnI00001%%~xI"^)
)
)
)
endlocal
There must be customized the fully qualified file name of IrfanView in the third line. There can be modified also the percent value of option /jpgq which defines the quality of the output JPEG file.
The command WHERE searches recursive in subdirectory images of the directory containing the batch file for files matching the wildcard pattern pa_10????.jpg with ignoring all other files. The found file names are output with full path and this list of file names is captured by FOR and processed line by line after WHERE finished. WHERE is executed in this case by one more cmd.exe started in background with option /c and the command line within ' as additional arguments and not by cmd.exe processing the batch file.
Read the Microsoft documentation 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 the embedded where command line with using a separate command process started in background.
Each image file with full name (drive + path + name + extension) is assigned one after the other to the loop variable I. For each file name one more FOR loop is used which processes just the full path to the current image file to assign this path with a dot appended to loop variable J. The dot at end means current directory, i.e. the directory containing current image file to process.
There is next checked with the first IF condition if for that image file does not exist already a matching pa_10????_merged.jpg file in which case there is nothing to do for the current image file. That means the batch file can be executed on same folder as often as wanted because of it runs IrfanView only for the source JPEG files for which the appropriate target JPEG file does not exist already.
The second IF condition checks if the back image exists also in the directory of current front image as otherwise nothing can be merged at all.
There is next checked with the third IF condition if the target directory exists already and this directory is created if that is not the case.
The last IF condition checks once again the existence of the target directory and if that exists now as expected, IrfanView is called with the appropriate options to create the merged image file in the target directory with the appropriate file name.
The closing round bracket ) on IrfanView command line must be escaped with ^ to be interpreted literally by cmd.exe to pass this closing parenthesis to IrfanView instead of interpreting it as end of one of the command blocks opened with ( above.
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 /? ... explains %~dp0 ... drive and path of argument 0 which is the batch file path always ending with a backslash
echo /?
endlocal /?
for /?
if /?
md /?
setlocal /?
where /?
Double click on the text file i_options.txt in program files folder of IrfanView for the description of the IrfanView options as used in the batch file.

Is there a CMD command to move a file to the next higher folder level?

I have something like saved a file here:
C:\Test\test.txt
I now want to move them via CMD so that the path is as follows:
C:\test.txt
Is that possible?
The command is:
move c:\test\test.txt c:\
The first argument is the source file.
The second argument is the target file or target-directory.
IF you just want to move the file exactly one level up the tree, and you don't know the name of the target directory, then you can use the .. indicator which means the parent-directory .
example:
move c:\Test\test.txt ..
will move the file into c:\Test .
If any part of the path or filename contains spaces then double-quote the source and/or target name appropriately.
See the help for the move command help move.
Yes, it is possible to move one or more files or folders up one level in folder hierarchy by using .. as described by Microsoft in the documentation about Naming Files, Paths, and Namespaces.
The simple approach in a command prompt window would be:
for %I in ("C:\test\test.txt") do for %J in ("%~dpI..\") do move "%~I" "%~fJ"
The command line in a batch file would be:
for %%I in ("%~1") do for %%J in ("%%~dpI..\") do move "%%~I" "%%~fJ"
%~1 references the first argument passed to the batch file which can be a file/directory name without or with a relative or with an absolute path, or even a wildcard pattern to move multiple files/directories up in the directory tree. The files/folders can be passed to the batch file also with a UNC path.
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.
for /?
move /?

I want to copy a directory excluding one file

I have used the xcopy command with /EXCLUDE switch but for that i have to make another file that contains the list of files to be excluded.
Below is the xcopy command i am using...
xcopy /EXCLUDE:C:\AA\excludedfiles.txt C:\AA d:\Models\Broker\NB\MOTNB0056
/S /E
where excludedfiles.txt contains the name of file that i want to exclude.
C:\AA is source and d:\Models\Broker\NB\MOTNB0056 is destination.
However i don't want to make extra file(excludedfiles.txt) for it. Suggest a command that exclude a file by giving just its path.
XCOPY is deprecated. It has been replaced by ROBOCOPY.
Open a command prompt window an run robocopy /? for help on command ROBOCOPY. In comparison to help of XCOPY output on running xcopy /? it has the option /XF to exclude one or more files specified after this switch and it is even possible to use wildcards.
So the command you might use is:
%SystemRoot%\System32\robocopy.exe C:\AA D:\Models\Broker\NB\MOTNB0056 /E /XF C:\AA\FileToExclude.ext
Some additional notes:
/S means copying with subdirectories, but without empty directories.
/E means copying with subdirectories with including empty directories.
It does not make sense to specify both on the command line.
It is advisable to specify target directory with backslash at end. This makes it clear for ROBOCOPY as well as for XCOPY that the target string specifies a directory and not a file. This is important in case of just a single file is copied as you can read in answer on batch file asks for file or folder. Both commands create the directory tree to target directory if this is necessary on having target directory specified with \ at end.
See Microsoft's documentation on Windows Commands and SS64.com - A-Z index of the Windows CMD command line on searching for a command for a specific file operation from command line or batch file.

writing a batch file for loop to rename and move files

I've never used Windows cmd scripting before; I'm trying to write a batch script, What I need to do:
I have a lot of folders, named numerically. Each one contains a file. All the files have the same name.
e.g.
folder1\file folder2\file
I want to rename and move the files, so they are named numerically and in the one folder
e.g.
newfolder\file1 newfolder\file2
My script for two test folders is:
FOR /L %%A IN (1,1,2) DO
(
move "folder%%A\file.txt" "newfolder\file%%A.txt"
)
I suspect this is all wrong. I get "the syntax of the command is incorrect".
Just move the opening parenthesis on the first line:
FOR /L %%A IN (1,1,2) DO (
move "folder%%A\file.txt" "newfolder\file%%A.txt"
)
Newlines aren't as invisible to the batch interpreter as in most other languages, meaning you have to explicitly tell it to look on the following lines.

Window Cmd Prompt - Move file with special character

i got a file by the filename
[vvv]_PHØDE:GREAKER_-_01_[720p][10bit][z11].mkv
how do i move the file with the move command at command prompt to make it this way
move "*GREAKER*.mkv" "PHODE_GREAKER_-_01_[720p][10bit][z11].mkv"
i want the second * to be replace at the destination as _-01[720p][10bit][z11] after the breaker.
In linux we can use regex pattern like (*.?) something like this , but how do i move it at window.
to take away this [vvv]_PHØDE:and make it as the string "PHODE"
On windows, MOVE is mainly used to move a file from one folder to another. It can only rename the file if the MOVE command is operating on a single file. If you are using wildcards in your source file then you should use REN (or RENAME) instead.
But, you have another problem that is more problematic. You have the : character in your file name, which is not valid for Windows. This may be impossible to fix with standard Windows commands and utilities. Perhaps one of the following SuperUser links can help:
How to batch rename files copied from OSX to Windows with ':' in filenames?
How to force Windows XP to rename a file with a special character?
Files with illegal filenames
Try this:
setlocal EnableDelayedExpansion
for %%f in (*GREAKER*.mkv) do (
set name=%%~f
ren "%%~f" "PHODE_!name:~12!"
)
endlocal

Resources