Batch File to Open Multiple PDFs | Only Opening 1 at a Time - batch-file

I recently "discovered" batch files - and have made a few successful ones to help open tedious amounts of files. However, this morning when trying to make on to open 45 pdfs at the same time it wouldn't work.
I used the instructions from here (under Kenp94's answer, and picture below). However, it just opens one at a time and waits until I close the opened pdf before opening the next. I would like to open them all at the same time.
My file looks like this: and is saved in .bat format.
How do I go about getting my files to open all at the same time.
That said, I have checked Opening multiple PDF documents using batch file and Creating a PDF file tracker as Batch file and I feel my approach is different enough that is warrants a separate question as opposed to gleaning the answer from there - or perhaps I simply don't understand Batch files well enough...
Thanks!

Possible solutions from a batch-file:
#For %%I In (*.pdf)Do #Start "" "%%I"
This however suffers from a potential issue, in that *.pdf matches all extensions which begin with .pdf.
To properly limit it to only .pdf extensions, you could use the internal Dir command together with findstr:
#For /F Delims^=^ EOL^= %%I In ('Dir /B/A-D "*.pdf" 2^>NUL^|FindStr ILE ".pdf"')Do #Start "" "%%I"
Alternatively, you could use Where.exe:
#For /F Delims^=^ EOL^= %%I In ('Where .:*.pdf" 2^>NUL')Do #Start "" "%%I"

Use the /WAIT switch to the start command
for %%v in (*.pdf) do start "" /WAIT "%%v"

Related

7zip creating empty archives with batch file

I want to zip everything in a folder, EVERYTHING, but into individually named archives. For some reason every solution on the internet only zips folders, or fails to work at all.
Currently, I have
for /d %%X in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%X.zip" "%%X\"
Which I interpret to mean
for = initiate a loop
/d = I don't know what this means
%%X = I don't know what this means
in = not sure, I think it means current directory
(*) = I don't know what this means
do = execute the next thing in "..."
"C:\Program Files\7-Zip\7z.exe" = the thing I want done.
a = add to archive
-m9 = max compression
"%%X.zip" = make it a zip file, though I still don't know what %%X is.
"%%X\" = even if I knew what "%%X\" meant I don't know why it's here.
I have figured out replacing %%X gives the archive a name, so it seems to copy the name of the thing being targeted.
So if I guess, I think /d is "target folders" and %%X is the name.
So
for /d %%X in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%X.zip" "%%X\"
Says in English as I understand it: for every folder name in the current directory, use 7z to max compress it into a zip of the same name... except I don't know what to replace /d with to make it target files instead of folders. And targeting specific extensions would be even better.
I tried googling what does "/d in cmd mean," "what does %%X mean", etc. I don't seem to be getting correct results in the search, I think I'm being too vague for google.
UPDATE:
for %%i in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%i.zip" "%%i\*.*"
seems to make a zip file NAMED each item in the folder, but does not actually add any files to them. I tried adding /f, but it didn't work at all when I did that.
Additionally, the first time I posted this it was closed as a duplicate of Batch script loop which has almost nothing to do with my problem. Yes, I have a loop, yes that addresses batch loops, but no, it does not come close to solving my problem since my problem isn't with the loop itself., or if it does I have absolutely no idea why or how. So please, explain it to me. I did see the section where it says %%X is the variable, but that just means I suppose X could be anything I want it to be, and since in my update I indicated a secondary issue, I think the problem I'm having is with 7z and not the bat file.
The for command can be very confusing at first, however there is many videos and sites that show examples of how to use it.
To start with try for /? to see the built in help information.
The below code should be what you are after if i understand your requirements correctly.. if not then this should help you understand the principles and adjust for your needs.
for /F "tokens=*" %%a in ('DIR /A-D /B /ON "C:\Test Folder\"') do (
echo Processing File: C:\Test Folder\%%a
"C:\Program Files\7-Zip\7z.exe" a -mx1 -tzip "C:\Test Folder\%%a.zip" "C:\Test Folder\%%a"
echo.
)
pause
Now lets go through it line by line...
for /F "tokens=*" %%a in ('DIR /A-D /B /ON "C:\Test Folder\"') do (
/F Tells it to work with files instead of directories(/D)
in (' ') Contains the command that finds the filenames. Note the ' marks at each end of the command...they are important.
%%a Represents each value of a filename that the in() command passes it.
do ( ) What it should do with each %%a value it receives.
Now we get to the command that is finding the filenames and passing to the do () section as %%a
('DIR /A-D /B /ON "C:\Test Folder\"')
You can find more info on the this by running dir /?
/A-D Tells it to ignore Directories... only list files.
/B Output just the file names and not anything else like sizes or it will confuse the for command.
/ON Feed the filenames to the do() command in alphabetical order
"C:\Test Folder\" The folder that contains all the files we want to list/perform actions on. Make sure you include the trailing slash. Also use the "" marks or it wont work if a folder has a space in its name.
Write(echo) to the screen a message showing which file it is about to do.
echo Processing File: C:\Test Folder\%%a
You can find more information on how to use the 7zip command line functions at https://sevenzip.osdn.jp/chm/cmdline/syntax.htm
"C:\Program Files\7-Zip\7z.exe" a -mx1 -tzip "C:\Test Folder\%%a.zip" "C:\Test Folder\%%a"
"C:\Program Files\7-Zip\7z.exe" Run this program.... and pass it the following information (arguments/switches)
a Add files rather than extract, etc.
-mx1 Use the fastest compression method...but less space efficient.
-tzip Use the ZIP compression format
"C:\Test Folder\%%a.zip" Save the new "zip" file as this. (%%a will be replaced with the name of the current file... aka ChuckNorris.mpg which would end up as ChuckNorris.mpg.zip)
"C:\Test Folder\%%a" This is the actual file you want to zip.

Batch: Preserve (creation-)date on copying files to another (flatten) folder structure, incl. renaming files to avoid doublettes

this is my first question, so I apologize beforehand if I write not as you are used to...
fact:
I've a deep folder structure with tons of files (images,videos and so on) so I want to copy that files to a flat structure for a better overview.
I want to keep (at least) the original date attributes: creation-date and last-modified date.
Problem 1) there are files with same name 00001.jpg in different folders which I want to have in same folder, so I want to add creation date/time to filename on copy process.
00001.jpg becomes 2015-11-17_11-23-35_00001.jpg
So far so good. Or not good...
Copy and XCopy doesn't give me an option to do that, without loosing at least the creation date information (I didn`t find a solution with both).
Now I try to copy the files (file by file) with robocopy to new folder and use ren on the copied file to "pre-set" the date/time information before the filename.
Here is a simple test.bat example:
setlocal enableextensions enabledelayedexpansion
robocopy . ./zzz original.txt /copy:DATSO
pause
rem :: formatted creation date of original file will be here, in real life
set "myDate=2015-11-17-_11-23-35"
rem rename "./zzz/original.txt" "!myDate!_renamed.txt" ::doesnt work: why? relative path??
rem :: this will do what I want - original creation date is kept on copy file
FOR %%A IN (zzz/original.txt) DO REN "%%~fA" "!myDate!_%%~nxA"
[possibly] Problem2) Is there a better way to do this, or could I run into thread problems (asynchronous execution). Could it be, that I try to rename a file before the robocopy has finished the copy process (e.g. for large files)?
Sorry I'm a totally batch newbie (also as poster in SO ;).
ThanX in advance for each tip and also for critics on my solution approach. Maybe I have the horse-blinkers on my head and dont see the easy solution?!
[edit: formatting of post]
[edit: content of post -> date/time in front of filename for better sorting]
It is possible to use command DIR to get recursive listed all files in the specified folder and its subfolders with creation date/time.
The format of the date/time depends on Windows Region and Language settings.
Example output for F:\Temp\Test on my machine with English Windows 7 and region is configured to Germany on running the command line dir F:\Temp\Test\* /A-D /S /TC:
Volume in drive F is TEMP
Volume Serial Number is 1911-26A4
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
1 File(s) 465.950 bytes
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
1 File(s) 360.546 bytes
Total Files Listed:
2 File(s) 826.496 bytes
0 Dir(s) 58.279.460.864 bytes free
This output is filtered with findstr /R /C:"^ Directory of" /C:"^[0123][0123456789]" to get only lines starting with  Directory of (note the space at begin) or with a number in range 00 to 39.
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
And this filtered output is processed by FOR loop and the commands executed by FOR.
#echo off
for /F "tokens=1-2*" %%A in ('dir "F:\Temp\Test\*" /A-D /S /TC ^| %SystemRoot%\System32\findstr.exe /R /C:"^ Directory of" /C:"^[0123][0123456789]" 2^>nul') do (
if "%%A %%B" == "Directory of" (
set "FilePath=%%C"
) else (
set "CreationDate=%%A"
set "CreationTime=%%B"
for /F "tokens=1*" %%I in ("%%C") do set "FileName=%%J"
call :RenameFile
)
)
goto :EOF
:RenameFile
set "NewName=%CreationDate:~-4%-%CreationDate:~3,2%-%CreationDate:~0,2%_%CreationTime:~0,2%-%CreationTime:~3,2%_%FileName%"
ren "%FilePath%\%FileName%" "%NewName%"
goto :EOF
It would be advisable to put command echo before command ren in last but one line to first verify the expected new file names.
ren "F:\Temp\Test\SimpleFile.ccl" "2017-09-25_17-26_SimpleFile.ccl"
ren "F:\Temp\Test\Test Folder\Test File.tmp" "2017-09-25_17-26_Test File.tmp"
Note: The batch file must be in a folder not processed by this batch file as otherwise the batch file itself would be renamed while running which breaks the processing of the batch file.
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 /?
for /?
goto /?
if /?
ren /?
set /?
By the way: WinRAR can add files into a RAR archive with creation and last access time in addition to last modification time and extract the files to a different directory with restoring also creation and last access time using SetFileTime function of Windows kernel.
currently I use Locale independent date. I use tokens from that for currrent date/time.
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
rem :: format it to YYYY-MM-DD_hh-mm-ss
set myDateTime=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%_%datetime:~8,2%-%datetime:~10,2%-%datetime:~12,2%
Thats not the problem.
To clarify:
The listing is also not the problem.
I loop throw all related files without a prob (except batch files and output dir and its sub tree ;).
My problem is:
I call robocopy for each file, then I rename the file to save the original creation date. My fear is that it makes problems (Multi-Threading?) for large files and for the number of calls (many thousend times)
Is batch execution really serialized? Is the process waiting for robocopy, that it has finished, before I try to rename file. Could I run into dead-locks for vry large files? I'll test it with some fake gigabyte-files.
Your suggestion, to use winrar sounds interesting.
If I could add all that files to a big archive (with structure) and at the end extract it to target dir... I'll try it ;)
If it doesn't work I will program it in java!
There I know what to do, thats my playground :D
I thought it would be easy to write a simple batch file, to do this for me, but it seems it's not as easy as I thought!
ThanX anyway

How to merge .sql files listed in a .txt into a single .sql script using batch?

I've searched high and low for a solution to this problem but have so far drawn a blank. I'm fairly new to batch scripts, so apologies if this turns out to be a stupid question.
I have a list of sql filenames in a .txt file which I would like to merge into a single sql script. The .txt file and the .bat file are in one subdirectory of a root location, and the sql scripts are in a separate subdirectory like so:
root\
batch files\
.bat
.txt
views\
.sql
I can read the file names out the .txt file quite happily and pass them to a subroutine using this:
for /f %%d in (IncludeList.txt) do call :Include_List "%%d"
goto :eof
The part that is causing me problems is the :Include_List subroutine. I need to be able to search the views\ subdirectory for each specified filename and then copy the content of it into a new script.
I tried the following, which I think is the nearest I've got it to working, without it actually working:
:Include_List
for /r %%f in ('DIR /B /S ..\Views\vw*.sql ^| find /i %~1') do type %%f >> _All_views.sql
It seems to be treating each part of this ('DIR /B /S ..\Views\vw*.sql ^| find /i %~1') as a filename and then failing to find any of them. It's also checking inside the batch files\ directory and not the views\ directory.
One additional requirement, is that this is part of a larger batch file, which would need to continue processing after the files had been looped through and written to the newly created _all_views.sql file.
Is what I am trying to achieve even possible with a batch file? Or am I just going to have to manually add each required file into the batch file like this
type ..\Views\[filename].sql >> _All_views.sql
Based on wOxxOm's answer my final solution is as follows:
setlocal EnableDelayedExpansion
for /f %%d in (IncludeList.txt) do (
for /f "delims=" %%f in ('DIR /B /S ..\Views\vw*.sql ^| find /i "%%d"') do type %%f >> _All_views.sql
)
I did away with the subroutine as it was causing issues when placed inside a larger batch file, but a nested for loop works perfectly for what I need.

How to selectively delete header lines from a .csv file using Windows batching (cmd)?

I am new to CMD batching and I am writing a small script that should take a file containing a list of .csv files and remove the header of every file except for two lines. One of the lines to keep contains the word "Timestamp", it looks like this:
"Timestamp: 2013-10-31T16:26:48.0110000".
The other line to keep signals the end of the header and it always starts with "Time(ms)" as the first token.
Initially I assumed the header to be of constant size (lines 1-20) and just kept line 2 and 20. Now I need my script to actually detect the end of the header as there are files with a 24-lines header.
Here is the script as it is right now
#if (#X)==(#Y) #end /* Harmless hybrid line that begins a JScript comment
setlocal
#echo off
for /f "tokens=*" %%a in (list.txt) do (
findstr /n "^" "%%a"|repl "^(1|10|11|12|1?[3456789]):" ":"|repl "^\d+:" "" A >"%%a.new"
move /y "%%a.new" "%%a" >nul
)
Credits to #dbenham who helped a lot to wrote the first script in an answer to a previous question and publish an utility named repl.bat.
Thanks in advance
David RODRIGUEZ
Here is a solution that should be robust. It uses a tool called findrepl.bat which is a grep-like tool written in a manner similar to repl.bat.
This uses a helper batch file called findrepl.bat - download from: https://www.dropbox.com/s/rfdldmcb6vwi9xc/findrepl.bat
Place findrepl.bat in the same folder as the batch file or on the path.
#echo off
for /f "delims=" %%a in (list.txt) do (
type "%%a"|findrepl "^" /e:"^Time\(ms\)" /b:"Timestamp" >"%%a.new"
type "%%a"|findrepl "^Time\(ms\)" /o:0:999999 >>"%%a.new"
move /y "%%a.new" "%%a" >nul
)
pause
This assumes that Time(ms) is in column 1 and in theory it will handle files with up to 1 million lines.

Batch file for opening most recent Malwarebytes' Anti-Malware Log

In Vista, I want to run a batch script to open the most recent file, based either on last modified date, or the date in the filename. It's for Malwarebytes' Anti-Malware logs in the %username&/appdata/roaming/Malwarebytes/Malwarebytes' Anti-Malware/Logs folder.
Log files are in this format here
mbam-log-2009-03-21 (00-20-21).txt
mbam-log-2009-03-21 (09-42-40).txt
mbam-log-2009-03-21 (11-02-43).txt
mbam-log-2009-03-21 (11-12-01).txt
mbam-log-2009-03-21 (12-01-42).txt
mbam-log-2009-03-21 (12-04-49).txt
mbam-log-2009-03-21 (14-01-41).txt
So its 24-hr format. I read on another page on here, and got this script here..
#echo off
dir *.txt /b /on > systext.bak
FOR /F %%i in (systext.bak) do set sysRunCommand=%%i
call %sysRunCommand%
del systext.bak /y
but it doesn't like the space in the filename.. always get an error.
Anyone have any ideas?
You actually have three problems in the script. The first is that %%i is likely to be set to the words with a filename- this can be fixed by using "delims=" in the for statement.
The second is that you need to quote spacey filenames in you call statement.
The third is that I'm not aware of a /y option for del, perhaps you mean del /f.
Amyway, give this one a shot:
#echo off
dir *.txt /b /on > systext.bak
FOR /F "delims=" %%i in (systext.bak) do set sysRunCommand=%%i
call "%sysRunCommand%"
del /f systext.bak
The following one-line batch file will open the most recently modified file:
for /f "usebackq delims=" %%i in (`dir /b /o-d`) do #start "%%i"&goto :eof
Using dir strikes me as much simpler than trying to dissect the date in the filename. You can also order by filename (as the date format is somewhat ISO-8601-ish is sorts well).
The goto :eof is just there to make sure only the most recent file will be opened and not all in order of date/time.
As for your space problem, surrounding the file name with quotes usually should fix that, but sometimes it's a little difficult to know where they have to be. Also, for by default tokenizes its input at spaces, that's why I included delims= in there which essentially says »Put everything into the variable and don't do any tokenizing«.
I know this is an old post, and I don't mean to revive it - I have an alternative approach to the question.
Malwarebytes' Anti-Malware includes the ability to reroute the log file to an alternate location (folder or specified file).
You can run "%programfiles%\malwarebytes' anti-malware\mbam.exe" /logtofile c:\logs\bob-mbam-log.txt. /logtofolder also works. (the above command assumes you're using a 32 bit system.)
When specifying a file, mbam appends instead of overwriting. So, that may make the log a little more difficult to parse.

Resources