Best to work on file systems that have short names disabled - they generally aren't needed unless you deal with very old lecacy programs. I imagine that would greatly simplify your problem. But sometimes you don't have control over the file system configuration.
MicrosoftIsKillingMe wrote:I know no DIR form that shows paths
The DIR /B option displays the full path of each file, but does not give timestamps or file sizes. If you don't need those values and/or you don't really need to sort by timestamp, then it should serve you well.
The FINDSTR search across linebreaks technique does work.
The code below finds all lines that precede a line ending with " a.txt", as well as all lines that end " a.txt"
Code: Select all
@echo off
setlocal
::Define LF variable containing a linefeed (0x0A)
set ^"LF=^
^" ::Above blank line is critical - do not remove
::Define CR variable containing a carriage return (0x0D)
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
setlocal enableDelayedExpansion
dir /a /od /s *.* | findstr /i /r /c:"^ Directory of" /c:" a\.txt$" | findstr /i /r /c:"!cr!!lf!.* a\.txt$" /c:" a\.txt$"
It seems like the following change to the last line ought to work just as well. It should return all lines that precede a line beginning with a 0 or 1 (the beginning of the date field's month), as well as any line that begins with 0 or 1. But there appears to be a new FINDSTR bug that I have not documented yet. The following partially works, but gives some extra unwanted folders in my hands:
Code: Select all
REM This does not work, even though it should!
dir /a /od /s *.* | findstr /i /r /c:"^ Directory of" /c:" a\.txt$" | findstr /i /r /c:"!cr!!lf![01]" /c:"^[01]"
But I imagine there is a better way to solve your problem, if only you fully described what you are really trying to accomplish. I'm assuming a given folder may return multiple files that you are interested in. The DIR /OD will sort by last modified date only within each folder, not across folders. Maybe that is what you want, but it seems unlikely.
You probably could use WMIC to accomplish your goal, but dealing with paths and timestamps is a pain in the ass with that system.
I suspect you could get what you want very elegantly with my
JREN.BAT utility. Short names do not interfere with its use. It was initially designed to provide sophisticated file/folder renaming capabilities using regular expressions, but it can also be used to search and format directory listings in most any way you want. To take advantage of that capability you must have some rudimentary JScript knowledge.
For example, the following will find all examples of "a.txt" in the folder hierarchy rooted at "c:\test", sorted by last modified date.
Code: Select all
jren "^" "ts({dt:'modified',fmt:'{iso-ts} '}) + parent() + '\\'" /list /s /p "c:\test" /fm "a.txt" /j | sort
Output would look something like
Code: Select all
2018-08-31T14:10:27.783-04:00 C:\test\viboras\a.txt
2019-04-08T10:33:58.160-04:00 C:\test\this and that\a.txt
2019-05-21T14:49:08.432-04:00 C:\test\xyz\a.txt
2020-04-06T10:51:47.538-04:00 C:\test\test\a.txt
2021-02-10T11:56:55.131-05:00 C:\test\a.txt
One obscure issue is the sort order could be wrong if you had multiple timestamps that were around 2am on a transition day between daylight savings and standard time. That could be fixed by using UTC times instead.
Code: Select all
jren "^" "ts({dt:'modified',tz:0,fmt:'{iso-ts} '}) + parent() + '\\'" /list /s /p "c:\test" /fm "a.txt" /j | sort
--OUTPUT--
Code: Select all
2018-08-31T18:10:27.783+00:00 C:\test\viboras\a.txt
2019-04-08T14:33:58.160+00:00 C:\test\this and that\a.txt
2019-05-21T18:49:08.432+00:00 C:\test\xyz\a.txt
2020-04-06T14:51:47.538+00:00 C:\test\test\a.txt
2021-02-10T16:56:55.131+00:00 C:\test\a.txt
As long as your locale formats timestamps in a way that can be parsed by JScript, then you can improve performance by using dt:'fsomodified' instead of dt:'modified'. That form will truncate all timestamps to seconds (milliseconds will be .000), and is much faster. But it does not work in some locales.
One of the nice features of JREN is you can use standard wildcards in your file mask. For example, an option of /FM "t*t.txt" specifies all .txt files whose base name begins and ends with t. Or if that is not sophisticated enough, you can use a Jscript (ecma) regular expression. For example, /RFM "^t.*t\.txt$" is the equivalent of /FM "t*t.txt"
Suppose you wanted to find all t*t.txt files, sorted by file name, then modified date. For this I pad each file name to a constant width to make it easy to read and sort.
Code: Select all
jren "^.*" "name(' ')+ts({dt:'modified',fmt:'{iso-ts} '})+parent()+'\\'" /list /s /fm "t*t.txt" /j | sort
--OUTPUT--
Code: Select all
test.bat.txt 2020-01-29T18:13:59.689-05:00 C:\test\
test.txt 2018-08-31T14:10:27.783-04:00 C:\test\viboras\
test.txt 2019-04-08T10:33:58.160-04:00 C:\test\this and that\
test.txt 2019-05-21T14:49:08.432-04:00 C:\test\xyz\
test.txt 2020-04-06T10:51:47.538-04:00 C:\test\test\
test.txt 2021-02-10T11:56:55.131-05:00 C:\test\
tsc_call_layout.txt 2015-06-22T15:11:24.583-04:00 C:\test\
Use JREN /? to get help, and JREN /?ts() to get help on all the many options of the ts() (timestamp) function.
Dave Benham