Command Prompt Wildcard File Delete Incorrectly Matching - batch-file

On a regular basis, I am trying to clean up some data folders for an ERP program prior to doing a backup and performing maintenance on the data tables. I've been using Windows Explorer to search for extraneous backup and temporary files prior to the full backup (the maintenance procedures create backup files during the process that aren't always removed), but I'd like to just run it all through a batch file to simplify and speed up the process. I'm filtering with the following:
*NGT????????????.old
*Wrk*????????????.m4t
Also, the command I'm using:
del /S /Q
Both of these work perfectly though the search function within Explorer. The first one works correctly in a command prompt, but the second doesn't. The series of ?s are created by the ERP software as a time stamp, to indicate a copy of the original was created at that time. And the second * represents a one or two character user ID that indicates the user that created the file (it isn't all that important except that the character length isn't always the same). When I try to filter in the command prompt with that second filter, not only does it grab the files I want it to, but it also grabs the original source files which DO NOT have a time stamp on them. For example, the following file names:
File 1) AR_AgedInvoiceReportWrk.M4T
File 2) AR_AgedInvoiceReportWrkTB081615903027.M4T
File 2 is the only one that should be deleted, but it will delete both File 1 and File 2. I've even tried using two or three ?s instead of the second * just to see if a difference would occur, but it doesn't.
Does the command prompt not recognize the ? the way Explorer does? What am I missing?

DIR and it seems other tools match the short file name and the long filename. Your short filenames have wrk as the leading characters and then you are matching a whole swag of any-character.
A solution is to use something like DIR /b /a-d and pipe it through findstr with a regexp, and that will match only the long filenames.

Related

For loop copying files in subfolders that contain hyphens [duplicate]

We are in the process of migrating files from one share to another. We have built a tool in which the user can select directories and/or individual files to be copied to a destination share. The tool generates an individual RoboCopy command for each of the files or directories in the collection that results from the selection made by the user.
We are having problems if an individual file to be copied starts with a dash, for instance:
robocopy c:\temp c:\temp2 -a.txt
RoboCopy bails out with: ERROR : Invalid Parameter #3 : "-a.txt"
We tried the usual suspects (quotes around the filename etc.), but so far nothing seems to work. Any idea how to get around this, without resorting to renaming the file prior to copying?
This appears to be a bug in robocopy; it has some other known similar ones:
https://support.microsoft.com/en-us/kb/2646454
Here's a possible workaround:
robocopy c:\temp c:\temp2 *-a.txt /xf *?-a.txt
*-a.txt will still match "-a.txt", but it also matches "x-a.txt", "xx-a.txt", etc.
The /xf file exclusion knocks out "x-a.txt", "xx-a.txt", and any other file with characters (specifically, at least one character) in front of the hyphen.
I've confirmed that the above command will match only "-a.txt" even if c:\temp also contains these files:
other folder\-a.txt
-a.txt1
-a1.txt
x-a.txt
xx-a.txt
I'm not 100% confident though, so you might want to think up some other filenames to test that against.

Changing Delimiter in Directory List

I'm a little bit stuck and need some help.
Currently have a process where completed work is stored in a directory as .txt files (the filename describes what the job was eg. Job1_Machine1_Randomly generated number.txt).
What I would like to do is run a dirlist via a batch file to easily extract the days work. I currently do this as:
dir *.* /s | find "%date%" >dirlisttoday.txt
The next part of my process is to upload the list into an Access database for matching and tracking, I use the files date and time stamp as a 'completed date'.
Currently the second process requires a manual manipulation as the Access import from .txt file only allows a single delimiter, (I have spaces between date/times and underscores in the title).
I can't use fixed width imports as Machine1 can vary in length. The directory is also used by other processes which can't be changed, so changing the filename isn't possible either.
I want to automate this process so it can be carried out by Windows Task Scheduler. Is there a line of script which can be added to my batch file to alter the directory list I create dirlisttoday.txt from:
31/08/2017 12:30 Job1_Machine1_Randomly generated number.txt
to:
31/08/2017 12:30 Job1 Machine1 Randomly generated number.txt

Getting a file name into a variable using a batch file

I've got a batch file which needs to perform operations on a specific file each day. So far, the file names have followed the pattern EX_2017-08-30.DAT which means I could use the following to get the exact filename for the day:
set today=%date:~-4,4%-%date:~-10,2%-%date:~-7,2%
set filename=EZ_%today%.DAT
Now I'm being told the filenames will change to include a timestamp, such as EX_2017-08-30-231859.DAT. However, the exact time won't be known beforehand (it gets set when a certain process completes).
I can't use a wildcard throughout the batch file because the filename is being written to an external file for another application to use, so I have to know the exact filename. Is there anyway that I can do a search with a wildcard and store the resulting complete filename into a variable?
If you can list the files in the directory your EX_* file is in, you can do:
for %%i in (EX_%today%-*.DAT) do (
set filename=%%i
)
The first line lists all files in the directory matching the date and the extension, and then it sets the last file to the filename variable. Be careful as this does not throw any warnings should there be more than one file matching the expression.
If you cannot list the directory, your only chance is bruteforce. There are only 24*60*60 possibilities of the filename, and if you go backwards in time, you should reach the desired file in just a couple of thousands of iterations, providing the task is usually completed close to midnight.

Strange Behavior with Wildcards and DIR Command in Command Prompt

I've noticed when using DIR in windows command line for one particular case wildcards don't function as I'd expect. Example:
dir *.doc
runs similar to
dir *.doc*
I've only noticed this behavior when the wildcard directory precedes the period (which is an important and frequent case). Whats even stranger is if you run either:
dir *.d
dir *.do
It will execute as expected. It's only once you hit 3 character extensions the strange behavior starts. I mentioned it runs similar to the command above because if the contents after the *. is not the extension it will not return the file. E.g.:
dir *.tar
will not return file.tar.gz but will return file.targa
Why is this and how can it be avoided?
The DIR command matches against both long and short names.
Windows file names that do not meet the old 8.3 DOS standard are automatically given a short file name alias that does meet the standard. (This can be disabled on NTFS drives)
For example, a file with a name of "file.targa" is assigned a short name of "file~1.tar" on my local hard drive. The rules for the short name are undocumented, and the assigned name varies depending on what names already exist within the folder when the file is created. But one thing that is consistent is that long extensions are truncated to the first three characters of the long extension.
Given that DIR searches both long and short names, you can now see that "*.tar" matches "file~1.tar" which is the short name for "file.targa"
This issue exists for pretty much every command that performs uses wild card file masks, including FOR, COPY, MOVE, REN, etc.
Workarounds
If your volume is NTFS, then you (or your administrator) can disable short names. But existing short names persist, it only disables generation of short names for future files. This is not a very practical solution, since you may not be in a position to know if any short file names exist.
If you simply need a list of files, without the other DIR info, then you can pipe the result of DIR /B through FINDSTR to get the desired result.
dir /b *.tar | findstr /le ".tar"
The extension is the part after the last dot. Anything before the last dot is the filename, including dots as ordinary characters.
Also remember that dir matches short and long names.

List a directory folder to a variable

I felt it was better to ask this separately rather than expect an answer from my comment on my previous post.
I already have variables set for the directory number %jobn% which is unique is there a way I can search for the unknown element to add to another variable, I know via the command line I can run Dir D09854* and I will get a single report with the full name, can this be collected somehow and add to a named variable?
S:\SWDA\HBOS>dir d09854*
Volume in drive S is Images
Volume Serial Number is FE8F-38FE
Directory of S:\SWDA\HBOS
18/02/2013 10:29 <DIR> D09854_Parent Test
I want to add the elements after "_" to a variable %DirDesc% so I can create the full path by combining %jobn%%DirDesc% to get "D09854_Parent Test"
dir d09854* /b will recover the full folder name in one line, without the extra cruft, if that's any use? What are you writing this widget in?
Does it have to be Good Old Fashioned DOS, or can the newer Command extensions be used?
With limited old DOS, I can't think of a way to get that into a SET Variable without piping it to a temporary batch file, having first ECHO'd a set variable= into it, and using >> in the pipe to append to it... and then CALL the temporary batch file to execute the command!

Resources