Batch file to run exe with unknown filename as arguments - batch-file

I have an exe for comparing 2 .csv files. And it works when I open cmd window, drag exe, type space, drag 1st csv file, type space, and drag 2nd file.
Now I want to automate it, and the problem is it is never on the same place, nor uses the same files for comparing...
What I got so far is following in batch:
%~dp0\Komparator.exe BC101.csv BC102.csv
pause
those 2 csv files are going to be in same folder, next to .exe and .bat file... but that "same folder" is not always the same, today its one location, another day is another folder
but I dont know how to automate those 2 arguments for file names, I just want it to recognize two .csv files near .exe and .bat
Thanks in advance!

You can read csv filenames and store them into batch variables using for cycle.
Here's an example, assuming your csv files are in the same directory as the batch file.
compare.cmd
#echo off
set FILE1=
set FILE2=
for /f "delims=" %%a in ('dir /b %~dp0*.csv 2^>nul ^| sort') do (
if defined FILE1 set "FILE2=%%~a" & goto :exit_loop
set "FILE1=%%~a"
)
:exit_loop
if not defined FILE1 echo first csv file not found!& goto :eof
if not defined FILE2 echo second csv file not found!& goto :eof
%~dp0\Komparator.exe "%~dp0%FILE1%" "%~dp0%FILE2%"

Related

How to check if zip or rar file contains 1 or more files?

For the purposes of saving space and organizing, I'm zipping bunch of files in my local and networked folders. They are mainly CAD files, like stp, igs, etc.
There are already existing zip files and some are extracted by other users, but the zip file still exists on the folders, which eats up space.
Is there a command line zip, rar, 7z. etc. to find out if an archive file contains only 1 file?
I'd like to figure this out as I'll extract the archives with single files in to the current directory whilst extracting archives with 1+ files to \archivename\ folder. Otherwise one folder with 30 STP files, will suddenly have 30 folders and 30 files extracted in them which I don't want.
I currently use a batch file with WinRAR to extract and another program to check for duplicates, then WinRAR batch to re-zip them based on file extension. (Reason: people use different archive methods and there are duplicates of files all over.)
Sample batch files:
for /F "delims=," %%f in ('dir *.stp /B' ) do (%path% a -afzip -r- -m5 -ed -ep -or -tl -y -df "%%f".zip "%%f")
for /F "delims=;" %%f in ('dir *.7z /B /S' ) do (%path% x -OR -ilogC:\Users\XXXX\Desktop\myLog.txt "%%f" "%%~dpf"\"%%~nf"\)
Once I can check for number of files in a zip, I'll add a recursive function.
I can use NTFS compression, but I also want to organize the folders, some folder have 1000 files in them, I surely want to reduce that to 1. These are mainly for archiving purposes.
Any help or thought would be appreciated.
I suggest the following commented batch file for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Extract all 7-Zip, RAR and ZIP archives in current directory into
rem subdirectories with name of archive file as name for subdirectory (-ad)
rem with running WinRAR for extraction in background (-ibck) which means
rem minimized to system tray with restoring also last access time (-tsa)
rem and creation time (-tsc) if existing in archive file and with skipping
rem files on extraction perhaps already present in the subdirectory with
rem same last modification time (-u), but overwriting automatically older
rem files in subdirectory if archive file contains an existing file with
rem a newer last modification time (-y) ignoring all errors (also -y).
for %%I in (7z rar zip) do "%ProgramFiles%\WinRAR\WinRAR.exe" x -ad -ibck -tsa -tsc -u -y *.%%I
rem If a subdirectory contains only 1 file, move that file to the current
rem directory with overwriting a perhaps already existing file with same
rem name in current directory and then remove the subdirectory.
for /D %%I in (*) do call :CheckSubDir "%%I"
rem Exit processing of the batch file without fall through to subroutine.
endlocal
goto :EOF
rem The subroutine CheckSubDir first checks for directories in directory
rem passed as parameter to the subroutine. A directory containing at
rem least one subdirectory is kept without any further processing.
rem If the directory does not contain a subdirectory, it searches for files
rem in the directory. If there are at least 2 files, the directory is kept
rem without any further processing.
rem But if the directory contains only 1 file, this file is moved to
rem current directory. Then the empty directory is deleted before exiting
rem the subroutine and continue batch file processing in calling loop.
rem Each directory containing no subdirectory and no file is removed, too.
:CheckSubDir
for /F "delims=" %%D in ('dir /AD /B "%~1\*" 2^>nul') do goto :EOF
setlocal EnableDelayedExpansion
set FileCount=0
for /F "delims=" %%F in ('dir /A-D /B "%~1\*" 2^>nul') do (
set /A FileCount+=1
if !FileCount! == 2 endlocal & goto :EOF
set "FileName=%%F"
)
if %FileCount% == 1 move /Y "%~1\%FileName%" "%FileName%"
rd "%~1"
endlocal
goto :EOF
Please read the comments for details what this batch file does on execution using WinRAR.
The batch file contains much more comment lines than real command lines.
2>nul in the last two FOR loops redirects the error message output by command DIR to handle STDERR in case of no directory or no file found to device NUL to suppress it. The redirection operator > must be escaped here with character caret ^ to be interpreted as redirection operator on execution of DIR command line and not already on parsing the FOR command line.
WinRAR supports many archive types on extraction. But WinRAR.exe is a GUI application and therefore does not support listing the contents of an archive file to console as Rar.exe supports.
The console version Rar.exe as well as free console application UnRAR.exe support both listing the archive file contents to handle STDOUT in various formats.
This difference on supported commands between WinRAR.exe and Rar.exe/UnRAR.exe can be seen by opening in WinRAR the help by clicking in menu Help on menu item Help topics, opening on help tab Contents the list item Command line mode, opening the list item Commands, clicking on list item Alphabetic commands list and comparing this list with the commands listed and described in text file Rar.txt in program files folder of WinRAR which is the manual for the console version.
Rar.txt lists and describes:
l[t[a],b] ... List archive contents [technical [all], bare]
v[t[a],b] ... Verbosely list archive contents [technical [all], bare].
Help of WinRAR does whether contain command l nor command v.
It would be of course also possible to run Rar.exe or UnRAR.exe on each *.rar file with command lb, count the number of lines output as done in above batch file to count the files and extract the *.rar archive file depending on the line count to current directory (1 line only) or to a subdirectory.
But it should be taken into account that on using bare list format and only 1 line output this line can be the name of an archived file or the name of an archived empty folder. The solution would be using standard list command and more analyze the attributes as well because a directory has attribute D while file does not have this attribute.
And for *.7z and *.zip files the same must be coded using 7z.exe or 7za.exe. The help of 7-Zip describes also the available commands and switches like the help of WinRAR.
But all those efforts do not make much sense in comparison to posted solution as the archive file has to be extracted at all and moving a file is done very fast as just the entry in file allocation table is modified and no data are copied or moved at all.
Running 7-Zip or Rar separately for first just listing each archive file contents, analyzing the list, and running 7-Zip or Rar once again on archive file for extraction is much slower than running WinRAR just 3 times (or less) to extract all archives and then move some files and remove some directories.
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 /?
dir /?
echo /?
endlocal /?
for /?
goto /?
move /?
rd /?
set /?
setlocal /?
See also the Microsoft TechNet article Using command redirection operators.
Taking the question literal the following batch uses 7z.exe (has to be reachable via the Path) list (l)-option to get the number of files included in the archive by filtering the last line.
#Echo off
Set Base=q:\Test
Pushd "%Base%"
For /f "delims=" %%A in (
'Dir /B/S/A-D *.zip *.7z *.rar'
) Do For /f "tokens=5" %%B in (
' 7z.exe l "%%~A" ^| findstr "files$" '
) Do If %%B equ 1 (
Echo Archive %%A contains 1 file
) else (
Echo Archive %%A contains %%B files
)
Popd
Sample Output:
Archive q:\Test\archiv.7z contains 135 files
Archive q:\Test\PoSh\powershellitunes\PowerScript-itunes.7z contains 1 file
Archive q:\Test\PoSh\_pdf_itextsharp\extract_pdf_pages_into_new_323689.zip contains 3 files
Archive q:\Test\_StackOverflow\Noodles\Filter0.8.zip contains 4 files
Archive q:\Test\2016\12\16\Path.rar contains 7 files
Archive q:\Test\_AllHelp.Win\allhelp.zip contains 7 files
Archive q:\Test\2017-02\pkzipc_40.rar contains 10 files

Changing folder name Batch filepath

In my batch file, I first create a Lala file in folder: C:Lala-20160322-othercode and next day it creates the file in Lala-20160323-othercode and so on. In the same batch file, I want to use this created file. Now i do not know what to write after -filepath
Since Lala is in a differnt folder every time.
My batchfile is in folder above Lala-20160322-othercode. How can I do this?
The file itself is always called Lala, but on my computer there are many folder (every day another folder) with Lala.
I am new to batch files. Many thanks!!!!!!!!!!!!!!!!
Code:
#echo off
setlocal
call "C:\folder\NameofPythonProgramm" Pythonfunction -filepath ????? -pythonfunction
First I had %1 where the questionmarks are, but I want this dynamic file path
Save this as Test.bat, and run from its folder in open Cmd Prompt to access the file Lala* in the dir corresponding to your desired month. Let me know if any errors.
#echo off
setlocal enabledelayedexpansion
set "dir=c:\Lala-Months"
set "cur_month=August"
FOR /R "%dir%" %%G in (.) DO (set "mon=%%G"
if not '!mon:%cur_month%=!'=='!mon!' echo %%G )
exit /b

Batch file Drag and Drop multiple files from one folder to a new folder Error

So I have the batch file below.
#ECHO OFF
FOR %%I IN (.) DO SET FolderName=%%~nxI
MKDIR "C:\%FolderName%"
for %%i in (%*) do (
move "%%~i" "C:\%FolderName%"
)
So when I drag and drop multiple files into the batch file, it will take the name of the folder that holds the files that I drag and drop and make a new folder at C:\ with the same name and then move the files into the new folder at C:\
Example: The folder that holds the files that I want to move is name Shop. Then the folder Shop is located at
...\ground\bell\tower\Shop
Using the batch file will make a new folder name Shop at C:\
Example
C:\Shop
The batch files works when I drag and drop about 100 files at once. The problem is that when I drag and drop 300 files at once, it returns the Error that says "The filename or extension is too long". I am able to move the files manually so I know that it can not be cause by a filename being too long.
Then I made a new batch file thinking maybe it is a problem with the move command or my for loop. So I wrote the batch file below.
#echo off
FOR %%I IN (.) DO SET FolderName=%%~nxI
MKDIR "C:\%FolderName%"
MOVE "%cd%\*.*" "C:\%FolderName%"
Now the second batch file above works just about the same as the first batch file. Just that with the second batch file, I only need to drag and drop one file from the folder that I want to move and it will move all the files in the first folder to a new folder at C:\ even if the first folder had 1000 files.
My question is why does the first batch file fail if I drag and drop too many files at once. Using the second batch file work, so it can not be because of the move command or is it? Since I am moving all the files from one folder to the other, the second batch file fits my need and was wondering if there will be any problems with the second batch file or a better way of doing this.
When you Drag-n-Drop Files on you Bat File, your Bat is actually called as if you would have called it in your command prompt. So if you drag three files on your Bat i.e.
Testfile.txt
Testfile.md
Testfile.jpg
Then actually your Bat is called like this:
C:\MyBatch.BAT Testfile.txt Testfile.md Testfile.jpg
If you call more it is obviously something like:
C:\MyBatch.BAT Testfile.txt Testfile.md Testfile.jpg Testfile01.txt Testfile01.md Testfile01.jpg Testfile02.txt Testfile02.md Testfile02.jpg Testfile03.txt Testfile03.md Testfile03.jpg Testfile04.txt Testfile04.md Testfile04.jpg Testfile05.txt Testfile05.md Testfile05.jpg etc...
Ah, can you read the rest of the line? Ok, this is not as long as 1000 Files but get the point what the difference is in your scripts. Your command line buffer will not be able to capture that much input.
Actually the size of how many characters you can enter in you command prompt varies a bit from system to system, but there was something like 8k in winXP, i reckon it is still the same.
http://support.microsoft.com/kb/830473 <-- that could help more concerning max.
And since the length of your command prompt is so "short" you have to find different methods for longer file trails - as you did - you could also overcome this, if you output the files you want to copy in a text file and then use that as input for your copy bat.
dir /b >filelist.txt
so now that you have this file list, then you just read the text file line by line:
for /f "delims=" %%i in (filelist.txt) do echo D|xcopy "C:\FolderName\%%i" "c:\temp\%%i" /i /z /y
so this will actually read your file list.txt and will (for each filename in list) press D key and pipes it to the XCopy command.
So piping a filelist to your command is a much better way, where actually in your case, if you really want the whole dir and not just a selection, copying directories is faster than copying file by file.
Hope you Question is answered.
If I am not mistaken, you are trying to create a folder with the parent folder as name. So before you ask again the same question in another post, I will code what you are seeking.
#echo off
setlocal
set "destination=c:\destination"
for %%i in (%~1) do set "parent=%%~pi" &goto:next
:next
for %%i in ("%parent:~0,-1%") do set "parent=%%~nxi"
for %%i in (%*) do (
echo:
if not exist %destination%\%parent%\nul ( mkdir "%destination%\%parent%" )
move "%%~i" "%destination%%parent%"
)
In addition, a command with many arguments is not a problem in the previous code.
For example: Write a batch file with the following code
#echo off
setlocal
set "destination=c:\destination"
for %%i in (%~1) do set "parent=%%~pi" &goto:next
:next
for %%i in ("%parent:~0,-1%") do set "parent=%%~nxi"
for %%i in (%*) do (
echo:
if not exist %destination%\%parent%\nul (echo mkdir "%destination%\%parent%")
echo move "%%~i" "%destination%%parent%"
)
call it test-move.bat and put the following long command-line of 250 parameters in cmd:
test-move.bat TestFile001.txt TestFile002.txt TestFile003.txt TestFile004.txt TestFile005.txt TestFile006.txt TestFile007.txt TestFile008.txt TestFile009.txt TestFile010.txt TestFile011.txt TestFile012.txt TestFile013.txt TestFile014.txt TestFile015.txt TestFile016.txt TestFile017.txt TestFile018.txt TestFile019.txt TestFile020.txt TestFile021.txt TestFile022.txt TestFile023.txt TestFile024.txt TestFile025.txt TestFile026.txt TestFile027.txt TestFile028.txt TestFile029.txt TestFile030.txt TestFile031.txt TestFile032.txt TestFile033.txt TestFile034.txt TestFile035.txt TestFile036.txt TestFile037.txt TestFile038.txt TestFile039.txt TestFile040.txt TestFile041.txt TestFile042.txt TestFile043.txt TestFile044.txt TestFile045.txt TestFile046.txt TestFile047.txt TestFile048.txt TestFile049.txt TestFile050.txt TestFile051.txt TestFile052.txt TestFile053.txt TestFile054.txt TestFile055.txt TestFile056.txt TestFile057.txt TestFile058.txt TestFile059.txt TestFile060.txt TestFile061.txt TestFile062.txt TestFile063.txt TestFile064.txt TestFile065.txt TestFile066.txt TestFile067.txt TestFile068.txt TestFile069.txt TestFile070.txt TestFile071.txt TestFile072.txt TestFile073.txt TestFile074.txt TestFile075.txt TestFile076.txt TestFile077.txt TestFile078.txt TestFile079.txt TestFile080.txt TestFile081.txt TestFile082.txt TestFile083.txt TestFile084.txt TestFile085.txt TestFile086.txt TestFile087.txt TestFile088.txt TestFile089.txt TestFile090.txt TestFile091.txt TestFile092.txt TestFile093.txt TestFile094.txt TestFile095.txt TestFile096.txt TestFile097.txt TestFile098.txt TestFile099.txt TestFile100.txt TestFile101.txt TestFile102.txt TestFile103.txt TestFile104.txt TestFile105.txt TestFile106.txt TestFile107.txt TestFile108.txt TestFile109.txt TestFile110.txt TestFile111.txt TestFile112.txt TestFile113.txt TestFile114.txt TestFile115.txt TestFile116.txt TestFile117.txt TestFile118.txt TestFile119.txt TestFile120.txt TestFile121.txt TestFile122.txt TestFile123.txt TestFile124.txt TestFile125.txt TestFile126.txt TestFile127.txt TestFile128.txt TestFile129.txt TestFile130.txt TestFile131.txt TestFile132.txt TestFile133.txt TestFile134.txt TestFile135.txt TestFile136.txt TestFile137.txt TestFile138.txt TestFile139.txt TestFile140.txt TestFile141.txt TestFile142.txt TestFile143.txt TestFile144.txt TestFile145.txt TestFile146.txt TestFile147.txt TestFile148.txt TestFile149.txt TestFile150.txt TestFile151.txt TestFile152.txt TestFile153.txt TestFile154.txt TestFile155.txt TestFile156.txt TestFile157.txt TestFile158.txt TestFile159.txt TestFile160.txt TestFile161.txt TestFile162.txt TestFile163.txt TestFile164.txt TestFile165.txt TestFile166.txt TestFile167.txt TestFile168.txt TestFile169.txt TestFile170.txt TestFile171.txt TestFile172.txt TestFile173.txt TestFile174.txt TestFile175.txt TestFile176.txt TestFile177.txt TestFile178.txt TestFile179.txt TestFile180.txt TestFile181.txt TestFile182.txt TestFile183.txt TestFile184.txt TestFile185.txt TestFile186.txt TestFile187.txt TestFile188.txt TestFile189.txt TestFile190.txt TestFile191.txt TestFile192.txt TestFile193.txt TestFile194.txt TestFile195.txt TestFile196.txt TestFile197.txt TestFile198.txt TestFile199.txt TestFile200.txt TestFile201.txt TestFile202.txt TestFile203.txt TestFile204.txt TestFile205.txt TestFile206.txt TestFile207.txt TestFile208.txt TestFile209.txt TestFile210.txt TestFile211.txt TestFile212.txt TestFile213.txt TestFile214.txt TestFile215.txt TestFile216.txt TestFile217.txt TestFile218.txt TestFile219.txt TestFile220.txt TestFile221.txt TestFile222.txt TestFile223.txt TestFile224.txt TestFile225.txt TestFile226.txt TestFile227.txt TestFile228.txt TestFile229.txt TestFile230.txt TestFile231.txt TestFile232.txt TestFile233.txt TestFile234.txt TestFile235.txt TestFile236.txt TestFile237.txt TestFile238.txt TestFile239.txt TestFile240.txt TestFile241.txt TestFile242.txt TestFile243.txt TestFile244.txt TestFile245.txt TestFile246.txt TestFile247.txt TestFile248.txt TestFile249.txt TestFile250.txt

Update text file with the name and also run an exe using batch file

I would like to do below things for every single file for all the the files with the ext .mtc inside a particular directory in a loop using batch script. Can someone please help?
Output the name of file in a text file in a variable
Run my application exe
Pass the file name variable from the text file (in step 1) to another batch file so that it can be used to output the same from my 2nd batch file
*Basically i want to retain the name of the file stored in my 1st batch file to my 2nd batch file
I am able to do step 2 of running my application for each of the mtc file but not able to do step 1 and step 3.
Something like this :
#echo off
for /f "delims=" %%a in ('dir /b/a-d *.mtc') do call:execute "%%a"
exit /b
:execute
echo Treating : %1
Yourexe.exe
call your_second_bat.bat %1
And your second batch will get the value of the .mtc file in %1
your_second_bat.bat :
#echo off
echo Value received from My first bat is [%~1]

Batch read and rename from text file issue?

I'm a beginner with .bat files, and I'm attempting to rename multiple drawing (.dwg) files using a list generated in notepad. The notepad list contains a list of drawing numbers that look like this:
01013-13000p001
06301-12550p001
etc..
There is hundreds of them, and I want to take those numbers from the text and put it into a blank series of dwg files that are generic named for now (drawing.dwg, drawing(2).dwg, drawing(3).dwg etc..) I've only come up with a way to read a text file, but cant figure out how to take from the text file and rename multiple drawing files with it. Below is as far as I have gotten, after failed attempts of trying to take whats read from a text file and put it into the .dwg files. I plan on working this out in all the same directory, and any suggestions will be greatly appreciated. Thanks.
#echo off
for /f "tokens=* delims=" %%x in (dwgNumbers.txt.txt) do echo %%x
pause
would
for /f "delims=" %%x in (dwgNumbers.txt.txt) do echo copy /b "blank generic drawing.dwg" "%%x.dwg"
(as a batch line) do what you want? - note that the ECHO keyword is there to show what would be done. The echo keyword needs to be removed to actually execute the copy.
This will take the numbers from .txt, renaming the existing .dwg files with the data readed. If there are more files that numbers in .txt, it will rename until number exhaustion, no more.
for loop is using a dir command to get the list of files to avoid the case of files that after being renamed falls under the filter of the for and gets reprocessed.
This code has a echo command included in rename line to prevent data loss in case of malfunction. When the output to console is what is needed, remove the echo command from the rename line.
#echo off
rem Prepare environment
setlocal enableextensions enabledelayedexpansion
rem Read input file for numbers
< dwgNumbers.txt (
rem Process dwg files in directory
for /f "tokens=*" %%f in ('dir /b *.dwg') do (
rem Get number from input file
set "number="
set /p "number="
rem If there is a number, rename the file
if defined number echo ren "%%~f" "!number!.dwg"
)
)
rem Clean
endlocal

Resources