I would like to locate some files which I saved on a certain date. I have tried using file explorer, but the task is quite a long task to look through all the files.
Is there an easier way on cmd (or file explorer)?
Help would be much appreciated!
dir has no filter for the date. You need a different approach:
for /r "<startfolder>" %a in ("<filemask>") do #echo %~ta %~fa |findstr /lbc:"<date>"
Example:
for /r "C:\" %a in ("*.jpg") do #echo %~ta %~fa |findstr /lbc:"22.07.2020"
(obviously, adapt the date-format in the findstr command to your system)
Note: this is directly on command line. If you want to use it in a batchfile, double each % to %%a, %%~ta, and %%~fa accordingly.
If you don't care for a clean output, a "quick and dirty" approach using dir:
dir /s "C:\*.jpg |findstr /lbc:" Verzeichnis" /lbc:"22.07.2020"
(obviously again, adapt the date-format and the " Verzeichnis"
(English: " Directory") in the findstr command to your system/language).
The following idea uses your own profile path as the base location for the search, and is searching for files modified on 3rd May 2021.
%SystemRoot%\System32\Robocopy.exe "%UserProfile%" NULL /FP /L /MaxAge:20210503 /MinAge:20210504 /NC /NDL /NJH /NJS /NS /S
Simply use your target date in YYYYmmDD format as the MaxAge, and the day after that as the MinAge in the same format.
If you need to make modifications to the base location, or learn more about the command options used, please open a Command Prompt window, type robocopy /?, and press the ENTER key.
Related
I need to do some very big Windows searches for some specific searchterms in th contents of all the files in a folder and all sub-folders. The GUI search facility is not finding all my tests, so I would like to try to use find via the cmd.
I can list all filenames in raw data format using:-
dir /S /B
I can successfully search for the searchterm in thecontents of all files in a single folder using :-
find "Searchterm" *.*
But there are thousands of recursive sub-folders, so when I pipe the output from the dir listing to the find (and exclude the filename parameter):
dir /S /B | find "Searchterm"
I am getting no results.
Furthermore, I have also successfully sent all the dir /B /S filenames to a text file:-
dir /S /B >> filenames.txt
and using type to pipe the contents of each file from the list to the find :-
type filenames.txt | find "Searchstring"
This does not work either. What am I missing? Microsoft's documentation suggests exactly the same format in https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/find as I am trying.
The solution to your question(s) should be clear by reading the output from %SystemRoot%\System32\findstr.exe /? ENTERed in a Command Prompt window.
I'd advise that you use the /L, literal, option for your initial code.
Direct results example:
%SystemRoot%\System32\findstr.exe /I /L /P /S "Searchstring" *
If you first send the filenames to a text file, e.g. Dir /B /S /A:-D 2>NUL 1>"filenames.txt", you could use the following idea:
%SystemRoot%\System32\findstr.exe /F:"filenames.txt" /I /L /P "Searchstring"
Just be aware, in this case, that unless you include a path outside of the target tree when initially creating filenames.txt, it will include itself in its own content. That means your FindStr command will also pick up any matches in that file too.
So I am trying to create a batch file that will take a pdf file in the same directory as the batch file and output the file name (sans extension). I used this code to accomplish this:
#echo off
for /r "C:\Users\me\Test Folder" %%G in (*.pdf) do set "name=%%~nG"
This works fine. The next step is to search another directory and find a directory within the searched directory whose name matches the output of the above code (stored in the %name% variable). Here's what I tried:
dir "P:\Accounting\Acc Pay" | find %name% | set "loc=%%~dp"
The goal of the above code was to find only the directories that had the same name as the original pdf file and then set the drive and path of the output to a variable %loc%. I think this is where I messed up.
Once the path to the folder is set to %loc%, I then am supposed to finish with this line:
move .\*.pdf %loc%
This would take all the pdf files (there will only be one in the directory at once) in the directory with the batch file and move it to the path currently stored in the %loc% variable.
In total the code looks like this:
#echo off
for /r "C:\Users\me\Test Folder" %%G in (*.pdf) do set "name=%%~nG"
for /r %%A in ('dir "P:\Accounting\Acc Pay" | find %name%') do set "loc=%%~dpA"
move .\*.pdf %loc%
However, the code seems to move the pdf file into the same location it was already in (ie the folder with the batch file). I assume the %loc% variable is not working properly. Any help much appreciated.
Like #Magoo said (^|). And you surely want to add the following switches for the dir command: /b for "bare format" (name only) and /ad for "Attribute Directory" to return folder names only. find needs its's argument quoted, and for safety, the destination for the move command should also be quoted. Your find could benefit from /i to make it case-insensitive.
I personally would do it with nested loops to avoid creating superflouos variables:
#echo off
for /r "C:\Users\me\Test Folder" %%G in (*.pdf) do (
for /r %%A in ('dir /b /ad "P:\Accounting\Acc Pay" ^| find /i "%%~nG"') do (
move "%%G" "%%~dpA"
)
)
Bonus: should there be more than one .pdf file (maybe after the Weekend or Holidays), this would process all of them correctly in one go.
Depending on your naming structures, consider replacing find /i "%%~nG" with findstr /iblc:"%%~nG" (see findstr /?to find out what the switches mean)
(Note to prevent confusion: findstr is the only command (as far as I'm aware) that supports concatenating switches into one. /iblc is the same as /i /b /l /c)
I'm trying to list out file names excluding their extension,
How I want it:
File1
File2
File3
How it currently is:
File1.txt
File2.txt
File3.txt
I tried using
#echo off
dir /A:-D /B
pause
but it isn't working. I tried it in both a batch file and in command prompt.
Am I using the right command?
Use FOR and ECHO to achieve this
For example, assuming the extension is always .txt:
for %f in ("*.txt") do #echo %~nf
Instead of using DIR, we are using the FOR command to go through the list and sending each one to ECHO, with the "~n" option inserted into the %f, to cause the extension to be not shown.
An alternative is
FORFILES /c "cmd /c echo #fname"
However with this I get quotation marks around each output filename, which isn't what you want.
If running inside a batch file, you need to double the %'s for variables
for %%f in ("*.txt") do #echo %%~nf
If you need to handle multiple file extensions
As long the directory doesn't contain any subdirectories whose names have an extension, you can generalise the *.txt to *.*:
for %f in ("*.*") do #echo %~nf
If you may have some filenames with only an extension
Where the file has an extension but nothing before it, e.g. .gitignore, the resulting empty ECHO command will output an inane message, such as ECHO is on. To avoid this ruining your onward plans, you can filter out lines containing ECHO is, with the FIND command and the /V option:
for %f in ("*.*") do #echo %~nf | find /v "ECHO is"
If your local language causes DOS to output something other than ECHO is then this filtering will not work. And it will miss any file that happens to contain ECHO is in the filename.
To search subdirectories too, add '/R' to the 'for'
for /R %f in ("*.png") do #echo %~nf | find /v "ECHO is"
Conclusion
This is all crazy, of course, but this is the agonising price we pay for using Batch language instead of an actual sensible language. I am like an alcoholic, promising to all and sundry that I will never write a line of Batch code again, and then finding myself coming back to do so again, sheepishly.
It'll be much easier in PowerShell
(Get-ChildItem -File).BaseName
or
Get-ChildItem | ForEach-Object { $_.BaseName }
Get-ChildItem can be replaced with the aliases ls, gci or dir and ForEach-Object can be replaced with %
So from cmd you can run either of these to achieve the purpose
powershell -Com "(ls -File).BaseName"
powershell -C (ls^ -File).BaseName
powershell (ls^ -af).BaseName
To add to Eureka's answer, the vanilla dir command cannot achieve what you're looking for.
C:\Users\jacob>dir /?
Displays a list of files and subdirectories in a directory.
DIR [drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N]
[/O[[:]sortorder]] [/P] [/Q] [/R] [/S] [/T[[:]timefield]] [/W] [/X] [/4]
[drive:][path][filename]
Specifies drive, directory, and/or files to list.
/A Displays files with specified attributes.
attributes D Directories R Read-only files
H Hidden files A Files ready for archiving
S System files I Not content indexed files
L Reparse Points - Prefix meaning not
/B Uses bare format (no heading information or summary).
/C Display the thousand separator in file sizes. This is the
default. Use /-C to disable display of separator.
/D Same as wide but files are list sorted by column.
/L Uses lowercase.
/N New long list format where filenames are on the far right.
/O List by files in sorted order.
sortorder N By name (alphabetic) S By size (smallest first)
E By extension (alphabetic) D By date/time (oldest first)
G Group directories first - Prefix to reverse order
/P Pauses after each screenful of information.
/Q Display the owner of the file.
/R Display alternate data streams of the file.
/S Displays files in specified directory and all subdirectories.
/T Controls which time field displayed or used for sorting
timefield C Creation
A Last Access
W Last Written
/W Uses wide list format.
/X This displays the short names generated for non-8dot3 file
names. The format is that of /N with the short name inserted
before the long name. If no short name is present, blanks are
displayed in its place.
/4 Displays four-digit years
Switches may be preset in the DIRCMD environment variable. Override
preset switches by prefixing any switch with - (hyphen)--for example, /-W.
Additionally, as an alternative to the suggestion to use ("*.txt"), if your file list includes multiple extensions you might either exclude different extensions or use *.* to get all files with a . in the name. Play around with that glob to get what you want out of it.
This is possible with a dir command and a for loop:
#echo off
for /F "delims= eol=" %%A IN ('dir /A-D /B') do echo %%~nA
If you want the full path without the extension, try:
#echo off
for /F "delims= eol=" %%A IN ('dir /A-D /B') do echo %%~dpnA
For cmd one-line:
for /F "delims= eol=" %A IN ('dir /A-D /B') do echo %~nA
And for the full path without the extension, try:
for /F "delims= eol=" %A IN ('dir /A-D /B') do echo %~dpnA
These small programs, loop through all the files in the folder except directories, and echo only the filenames/full paths without the extension.
dir -Name -File
This is for PowerShell
I need to copy the contents of a folder to another folder using a batch file - the problem I'm facing is that one of the parent folders will change every day, being named after today's date. So, for example, I have the following command:
xcopy /Y /S "\\auto-jenkins\Builds\2017\R1\\[0822]\EN\\*.*" "C:\Users\Administrator\Desktop\EN"
This works fine today, unfortunately tomorrow the [0822] will not exist and the files I need will be under [0823]. Does anyone know of a way I can use a wildcard in place of [0822]?
The [08**] folder will be the only folder below \R1 if that helps...
Does anyone know of a way I can use a wildcard in place of [0822]?
You don't need a wildcard. Use the current date (in the correct format) instead. Use the following batch file.
CopyFiles.cmd:
#echo off
setlocal
rem get the date
rem use findstr to strip blank lines from wmic output
for /f "usebackq skip=1 tokens=1,2" %%g in (`wmic Path Win32_LocalTime Get Day^,Month ^| findstr /r /v "^$"`) do (
set _day=00%%g
set _month=00%%h
)
rem pad day and month with leading zeros
set _month=%_month:~-2%
set _day=%_day:~-2%
xcopy /Y /S "\auto-jenkins\Builds\2017\R1[%_month%%_day%]\EN*.*" "C:\Users\Administrator\Desktop\EN"
endlocal
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
for /f - Loop command against the results of another command.
wmic - Windows Management Instrumentation Command.
Since there is only a single folder in the R1 directory anyway, you can use for /D to get its name:
for /D %%D in ("\\auto-jenkins\Builds\2017\R1\*") do (
xcopy /Y /S "%%~D\EN\*.*" "C:\Users\Administrator\Desktop\EN"
)
The * is a global wild-card that stands for any number of arbitrary characters. Instead of it, you could also use [????] so your folder name must consist of exactly four characters in between [].
You can use the automatic date variable %date which is country specific:
xcopy /Y /S "\auto-jenkins\Builds\2017\R1\[%date:~3,2%%date:~0,2%]\EN\*.*" "C:\Users\Administrator\Desktop\EN"
Here, the month and the day are extracted from the date string. First number is the start position (starting at 0), next number is the length.
In short: In Windows CMD, I need to list all the contents in all of the sub-directories of a folder, and their date-created or date-modified timestamps.
In long:
I want to regularly run a command which outputs the creation datetimes of files we upload to our FTP. I'm able to do this for one folder at a time and get the output in a text file (dir . h:\uploadtimes.txt). I'd like to do this for over 100 folders in one go. Filename and datetime-created is all I need.
THANKS!
dir /? could help (or read command reference); one could use /TC switch instead of /TW one:
dir X:\folder\*.* /S /A-D /-C /TW > h:\uploadtimes.txt
Another approach giving fully qualified file names but always date-modified timestamp regardless of /T switch unfortunately:
for /F "delims=" %G in ('dir X:\folder\*.* /S /B /A-D') do #echo %G %~TG > h:\uploadtimes.txt
Resources (required reading):
(command reference) An A-Z Index of the Windows CMD command line
(additional particularities) Windows CMD Shell Command Line Syntax
(%~G etc. special page) Command Line arguments (Parameters)