0
@Echo On
FOR %%f IN (*.jpg) DO (
    forfiles /M "%%f" /C "cmd /V:ON /c set fn=@ftime"
    echo %%fn%%
)
pause

I want to get @ftime in FOR loop, but this isn't working. Maybe there is another way to get modify time of the file?

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Kot Shrodingera
  • 85
  • 1
  • 4
  • 12

3 Answers3

1

In your method, you are setting a variable fn within the cmd instance that is opened by forfiles, but this variable is no longer available in the cmd instance that runs your script.


You can use the ~t modifier of the for variable (so %%~tf in your code) to get the modification date and time, then split off the time portion by substring expansion (see set /?), if the featured resolution of minutes is sufficient (the "%%~nxF" portion just precedes the returned time with the current file name):

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for %%F in ("*.jpg") do (
    set "FTIME=%%~tF"
    rem The following line depends on region settings:
    echo "%%~nxF": !FTIME:~11!
)
endlocal
pause

Alternatively, you can use a for /F loop to split off the time part from the date:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%F in ("*.jpg") do (
    for /F "tokens=1,* delims= " %%I in ("%%~tF") do (
        echo "%%~nxF": %%J
    )
)
endlocal
pause

If you require a resolution of seconds as supported by forfiles, you need to echo the @ftime value within forfiles and capture that by a for /F loop, which iterates once only per each file (time) (@file returns the current file name, which is then held by "%%~K"):

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%F in ("*.jpg") do (
    for /F "tokens=1,* delims=|" %%K in ('
        forfiles /M "%%~F" /C "cmd /C echo @file^|@ftime"
    ') do (
        echo "%%~K": %%L
    )
)
endlocal
pause

Depending on your application, you might not need a separate for loop to walk through *.jpg files, because forfiles could do that on its own:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1,* delims=|" %%K in ('
    forfiles /M "*.jpg" /C "cmd /C echo @file^|@ftime"
') do (
    echo "%%~K": %%L
)
endlocal
pause
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • How can I use filename in this cycle? – Kot Shrodingera Dec 28 '15 at 15:02
  • If you're talking about the `for` loop, you can use `~nx` instead of `~t` to get the file name + ext. -- type `for /?` in a command prompt window and check out all the possibilities at the end of the help text; if you mean the `forfiles` loop, you need to state `@file` instead of `@ftime` -- type `forfiles /?` in command command prompt to get a full list of all the available `@`-variables... – aschipfl Dec 28 '15 at 15:10
  • I dont get it. How can i echo filename after `echo %%L`?. I need seconds – Kot Shrodingera Dec 28 '15 at 17:38
  • Okay, I extended all the code snippets in my [answer](http://stackoverflow.com/revisions/34485131/3) so they return the file name plus the related file time now; I hope everything is clear now... – aschipfl Dec 28 '15 at 18:01
0

You cannot set variables in your batch file from a forfiles call because that one will always spawn a new shell. forfiles is a program, not a built-in command.

However, you can get the modification time with %%tf in your loop, without forfiles:

setlocal enabledelayedexpansion
FOR %%f IN (*.jpg) DO (
    set "fn=%%~tf"
    echo !fn!
)
Joey
  • 344,408
  • 85
  • 689
  • 683
0

If you need exactly FORFILES, just write output to tempfile:

...
set file=temp.txt
...
FORFILES /M "%%f" /C "cmd /c echo @ftime >> %file%"
FOR /F "usebackq tokens=1,*" %%a In ("%file%") Do (Set fn=%%a | echo %fn%)
DEL %file% /q