3

I've done some digging and can't seem to find a simple answer anywhere, maybe I'm looking in the wrong places. I simply want to sort files by their modification time, oldest to newest. Is this possible?

for %%i in (Input/*.json) do (

)
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • 1
    Open a command prompt window and run `dir /?` and next `for /?` and read the output help pages for these two [Windows Commands](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands) to understand following command line for your batch file: `for /F "eol=| delims=" %%I in ('dir Input\*.json /A-D /B /OD 2^>nul') do echo File "%%I" has time %%~tI`. I wrote once a very long answer on [Bat file to delete files only when younger files are present](https://stackoverflow.com/a/47915658/3074564) with information which could be interesting for you, too. – Mofi Jun 21 '19 at 17:56
  • This works perfect, thank you. I'll give that a read, I have a lot to learn :) – user11588722 Jun 21 '19 at 18:01

2 Answers2

1

If you only want them sorted then DIR is going to be the fastest Route, you can parse that output using a FOR /F Loop.

This Code will give you Ascending Date:

FOR /F "tokens=*" %%A IN ('
  DIR /B
  /O:D
  /A:-D 
  Input\*.json
') DO (
  ECHO(Found: "%%~A"
)

The /O option changes the order. /O:D or /OD Orders Date Ascending (Oldest First) /O:-D or /O-D Orders Date Descending (Newest First)

The /A option changes the type of items selected. /A:-D or /A-D Selects File Items, /A:D or /AD Selects Directory items.

The /B option Outputs Only File Names unless the /S switch is used along with it to recurse the directory tree, in which case it will output file paths.

The only issue with this (without /S )is:

As you are looking into a subdirectory, instead of the same directory, you can not pull any of the other FOR variable info from the output.

IE: You can not use say %%~tAto print the Date/Time, and %%~fA Will give the wrong file path.

If those are required to be returned you will have to find the information separately or scrape info needed from the DIR cmd, or use the /S option which recurses sub directories.

Thanks @Michel de Ruiter for noting that, and drawing my attention ack to update this a bit , and now I will expand on your expanded bit.

If you would like to get the path or timestamp etc. from the for loop, but you don't want to waste time or get results form sub directories you can amend to the following version.

this uses Findstr to remove any subdirectories below the initial search directory using a basic regular expression.

FOR /F "tokens=*" %%A IN ('
  DIR /B
  /O:D
  /A:-D 
  Input\*.json
  ^| findstr /i /v "\\input\\.*\\.*"
') DO (
  ECHO(Found: "%%~A"
)

in this usage the findstr command is using these switches to match a regular expression which matches any sub directories where files might be matched (directoties without files are skipped due otthe options on the dir cmd as explained above)

The /i option means to match case-insensitive

The /v option means to exclude results that do match the pattern

The pattern appears within the double quotes "\\input\\.*\\.*" here this is a basic regex where the period . matches anything and the astrix * says to mathc the previou character any tmber of times so .* means match any caracter zero or more times.

\\ matches a directory path's backslash \ is an escape character in normal regex, in findstr we could o it either as \ or \\ to match correctly, I chose \\ because that is consistent with the defined syntax for regex across all platforms.

Finally we have to have a trailing `.\." to make sure we ignore all entries related to the sub directories.

Nice to note, that by using the findstr within the FOR loop's command portion which allows this to execute much more quickly.

Ben Personick
  • 3,074
  • 1
  • 22
  • 29
1

To improve on Ben's answer, just

  1. add /S to DIR to make %%~tA and %%~fA work (full paths), and
  2. use "tokens=*" with /F to support spaces in filenames (check FOR /?)

In other words:

FOR /F "tokens=*" %%a IN ('DIR /B /S /O:D /A:-D Input\*.json') DO (
 ECHO "%%a"
)
Michel de Ruiter
  • 7,131
  • 5
  • 49
  • 74
  • 1
    That's a good addendum to mine, I clearly wrote this on the train and clearly neglected to put int the put in the `"tokens=*"` which should have been done anyway on mine. I do recall that while i mentioned the /S feature if they want sub directories, but that's a valid work around , so long as they either have no sub directories, or we append `^|findstr /i /v ".*\\input\\.*\\.*"` to the `DIR` cmd in the `FOR` loop – Ben Personick Jan 04 '22 at 17:32