How can I echo subdirectory + all the files inside? - windows

Sorry, there is my updated question.
I want to echo all the subfolders and all the files with a specific extension that are inside those subfolders. I would like to echo them like this :
Subfolder 1 :
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder1\File1.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder1\File2.mjb"
Subfolder 2 :
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder2\File1.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder2\File2.mjb"
Subfolder 3 :
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder3\File1.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder3\File2.mjb"
At the moment, I only manage to echo all the files. So there is two things to see :
How can I echo both of this things.
How can I echo specific file only.
There is my actual code :
setlocal enableDelayedExpansion
set ext=".mjb"
for /f "delims=" %%F in ('dir /b /s /a-d "%_FolderName%"^| findstr /vile "!ext!"') do echo "%%F"
And this is my actual result (I'm trying this in a test_env) :
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier1.qds"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier2.txt"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier4.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier5.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier6.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier1.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier2.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier3.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier4.wmf"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier1.txt"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier4.pdf"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier5.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier6.mjb"

#ECHO Off
setlocal ENABLEDELAYEDEXPANSION
SET "_FolderName=u:\Users\546802\Desktop\outil_5s\env_test"
set "ext=mjb"
SET "currentdir="
for /f "delims=" %%b in ('dir /b /s /a-d "%_FolderName%\*.%ext%"') do (
IF "!currentdir!" neq "%%~dpb" (
SET "currentdir=%%~dpb"
FOR %%c IN ("%%~dpb.") DO ECHO %%~nxc :
SET "files_dir=%%~dpb"
SET "files_dir=!files_dir:%_FolderName%\=!"
ECHO !files_dir:~0,-1! :
)
echo "%%b"
)
GOTO :EOF
Somewhat unclear what you want to do.
Your code performs a findstr with the /v option, so it will select all lines that do not match the mask provided, but the mask provided is resolved to "".mjb"" because you are assigning the quotes within the set statement, then re-quoting it.
It's not clear what header you are asking for where the filename is ...5s\env_test\Plein1\Fichier2.mjb - which may have the same name as ...5s\env_test\Plein1\Plein1\Fichier2.mjb. Is it the direct parent name (plein1 for both instances) or should there be a distinction?
The dir statement above selects all of the .mjb files which appears to be your goal.
currentdir keeps trac of the last parent directory found. If it changes, I've shown two possibilities. The first potential header shown is simply the parent directory name.
The second is calculated by removing the starting directory name from the absolute pathname of the file.
Note that I changed metavariables because F can be confused with ~f (the full-filename modifier operator) and that my testing was performed on drive u: (my RAMdrive)

Thanks for your answer Magoo. Here is the exact thing of what I wanted exactly.
for /F "Tokens=1 Delims=" %%I in ('cscript //nologo explo_fichier.vbs') do set _FolderName=%%I
setlocal enableDelayedExpansion
set "ext=mjb"
set "currentdir="
for /f "delims=" %%b in ('dir /b /s /a-d "%_FolderName%\*.%ext%"') do (
if "!currentdir!" neq "%%~dpb" (
set "currentdir=%%~dpb"
for %%c IN ("%%~dpb.") do echo %%~nxc :
)
echo "%%b"
)
I have a script that opens me the file explorer so I can choose which folder I want to test :
explo_fichier.vbs
Const MY_COMPUTER = &H11&
Const WINDOW_HANDLE = 0
Const OPTIONS = 0
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(MY_COMPUTER)
Set objFolderItem = objFolder.Self
strPath = objFolderItem.Path
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder _
(WINDOW_HANDLE, "Select a folder:", OPTIONS, strPath)
If objFolder Is Nothing Then
Wscript.Quit
End If
Set objFolderItem = objFolder.Self
objPath = objFolderItem.Path
Wscript.Echo objPath
The goal of that is to get those informations so I can zip recursively all this files in a folder with the name of the parent folder. So my first step was getting those informations and now I will use a VBS script that zips everything as I want.

Related

Getting file time in a batch file (windows)

I'm looking for a way to retrieve the file time-- down to the SECOND-- in a batch file. I'm trying to do an operation on all files that have been modified more recently than another file.
I've used this method:
for %%a in (keyfile.dat) do set LAST_PUBLISHED_DATE=%%~ta
rem for %%x in (%LAST_PUBLISHED_DATE:/= %) do echo %%x
for /f "tokens=1,2 delims= " %%a in ("%LAST_PUBLISHED_DATE%") do (
set DATE=%%a
set TIME=%%b
)
for /f "tokens=1,2,3 delims=/" %%a in ("%DATE%") do (
set MON=000%%a
set DAY=000%%b
set YEAR=%%c
set MON=!MON:~-2,2!
set DAY=!DAY:~-2,2!
set YEAR=!YEAR:~-2,2!
)
for /f "tokens=1,2 delims=:" %%a in ("%TIME%") do (
set HOUR=000%%a
set MIN=000%%b
set HOUR=!HOUR:~-2,2!
set MIN=!MIN:~-2,2!
)
set INT_LASTPUBLISHEDDATE=%YEAR%%MON%%DAY%%HOUR%%MIN%
And I've been using that to turn the last modified date into an int which I can compare against other files. Works great. Except sometimes I might need to run this batch more often than once a minute.
Is there some extended way that I can also get "seconds" from the file modified time? The method above returns it in yyyy/mm/dd hh:mm format.
(Most ideal situation would be to just get the unix time of the last modification... haven't been able to locate any way to do that though!)
Thanks!
you can leverage vbs for this purpose.
#Echo Off & Setlocal EnableDelayedExpansion
(For /F "Delims=" %%G in ('TYPE "%~F0" ^| Findstr /BLIC::::') Do (Set "Line=%%G"&Echo/!Line:~3!))>"filetimes.vbs"
For /F "Delims=" %%G in ('cscript //nologo filetimes.vbs %~nx0')Do Set "%%G"
Set %~F0[
Exit /B
:::Set objFSO = CreateObject("Scripting.FileSystemObject")
:::if WScript.Arguments.Count = 0 Then
::: WScript.Quit
:::End If
:::strfileFolder = objFSO.GetAbsolutePathName(WScript.Arguments(0))
:::'this line only works with cscript
:::Set v = objFSO.GetFile(WScript.Arguments(0))
:::dm=v.DateLastModified
:::dc=v.DateCreated
:::da=v.DateLastAccessed
:::WScript.StdOut.WriteLine(strfileFolder&"[Created]="&dc)
:::WScript.StdOut.WriteLine(strfileFolder&"[Modified]="&dm)
:::WScript.StdOut.WriteLine(strfileFolder&"[Accessed]="&da)

Is there a command that can be moved to a folder by file name in Windows?

I want to read the file name with the command and automatically move it to the folder with the same name. What should I do?
example:
before processing
after processing
If I have files and folders with the same name, I want to move them to a folder with the same name.
What should I do? Do I have a cmd command?
I will provide both a solution to this exact question, and an alternative that I would suggest to handle this situation.
==========
~ Solution ~
==========
Copy/Paste the code below into an empty file, save, and execute.
#echo off
for /f "tokens=1,* delims=_" %%a in ('dir /b *.xlsx') do (
if not "%%a_%%b"=="%~nx0" (
if not exist %%a mkdir %%a
move "%%a_%%b" "%%a\"
)
)
You can change the "*.xlsx" to any other file extension, or change to "*.*" to work with ANY file extension.
Keep in mind though, this ONLY works with filenames that are formatted like the way you mentioned in your question.
===================
~ Alternative Solution~
===================
I would suggest the Shell Extension "Files 2 Folder" as an alternative. I came across a situation where I needed something similar to what you're asking a couple years ago, and this ended up working out great.
https://www.dcmembers.com/skwire/download/files-2-folder/
Here is another approach using regex in vbscript with a batch file :
#echo off & color 0A
Title Extract Title using Regex in vbscript
SetLocal EnableDelayedExpansion
#for /f "delims=" %%a in ('dir /b *.xlsx') do (
Call :Extract_Title "%%a" Title
If Defined Title (
If Not Exist "!Title!\" MkDir "!Title!\"
Move /-Y "%%a" "!Title!\"
)
)
Pause & Exit
::----------------------------------------------------------------------------------------
:Extract_Title <InputFile> <Title to be Set>
>"%tmp%\%~n0.vbs" (
echo WScript.StdOut.WriteLine Extract_Title(Data^)
echo Function Extract_Title(Data^)
echo Data = Wscript.Arguments(0^)
echo Set re = New RegExp
echo re.Global = True
echo re.IgnoreCase = True
echo re.Pattern = "(\S+|\S.+)_"
echo For Each Match in re.Execute(Data^)
echo Title = Match.SubMatches(0^)
echo Next
echo Extract_Title = Title
echo End Function
)
#for /f "delims=" %%A in ('cscript /nologo "%tmp%\%~n0.vbs" "%~1"') do set "%2=%%A"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
Exit /B
::----------------------------------------------------------------------------------------

Batch check and replace string then wait for a process

I need a batch file witch will:
check inside user.cfg file for string "g_language = Russian" and leave it if
finds it but if sting is set to "g_language = English" then set it to
"g_language = Russian"
wait for some.exe to start and when it is started
change string "g_language = Russian" to "g_language = English"
How can I do this?
I used this code but my result is:
Russian=g_language = English= Russian
#echo off &setlocal
set "search=g_language = Russian"
set "replace=g_language = English"
set "textfile=user.cfg"
set "newfile=user.bak"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>"%newfile%"
del %textfile%
rename %newfile% %textfile%`
#echo off &setlocal
set "Russian=g_language = Russian"
set "English=g_language = English"
set "textfile=user.cfg"
set "newfile=user.bak"
Call :SwapLang Russian
Start "" some.exe
Timeout /t 5
Call :SwapLang English
Goto :Eof
:SwapLang %1 byRef
( for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal EnableDelayedExpansion
If /I "!line:~0,12!" Equ "g_language =" (
echo(!%1!
) Else (
echo(!line!
)
endlocal
)) > "%newfile%"
del %textfile%
rename %newfile% %textfile%
Goto :Eof
Heres an alternative to the great answer already given.
I haven't been able to test this, (please try it in a test environment first), and only do so if you feel you would benefit from the slightly different approach.
#Echo Off
Set "fexe=some.exe"
Set "fcfg=user.cfg"
Set "fbak=user.bak"
Set "sstr=g_language"
Set "rlng=Russian"
Set "elng=English"
If Exist "%fbak%" (If Not Exist "%fcfg%" (Copy "%fbak%" "%fcfg%"
) Else Copy "%fcfg%" "%fbak%") Else If Exist "%fcfg%" (Copy "%fcfg%" "%fbak%"
) Else Exit/B
QProcess "%fexe%">Nul 2>&1 &&(FindStr/IC:"%sstr% = %elng%" "%fbak%">Nul||(
Call :Sub "%rlng%" "%elng%"))||(
FindStr/IC:"%sstr% = %rlng%" "%fbak%">Nul||(Call :Sub "%elng%" "%rlng%"
Start "" "%fexe%"))
Exit/B
:Sub
(For /F Delims^= %%A In ('FindStr $ "%fbak%"') Do If /I "%%A"=="%sstr% = %~1" (
Echo %sstr% = %~2) Else Echo %%A)>"%fcfg%"
I have made it so that you should only need to check/adjust the items on lines 3 to 8.
The general idea:
If neither user.cfg and user.bak exist, exit.
If only one of user.cfg or user.bak exists copy one to the other.
If both user.cfg and user.bak exist, copy user.cfg to user.bak.
If some.exe is running and user.cfg's g_language is not English change it to English.
If some.exe is not running and user.cfg's g_language is not Russian change it to Russian and run some.exe.
Of course none of this matters if user.cfg changes do not take effect until some.exe is restarted.

Batch file to list all txt files with a certain filename and certain content on windows server 2008

I'm looking for a batch file that allows me to search for files, created within a certain timeframe (e.g. 2013-01-01 till 2013-01-20), with a specific name pattern (e.g. *foo.xml) that contain a certain string (e.g. "mySearchString").
I tried some stuff using the forfiles but it does not allow me to set a date period - it only allows me to search for files before or after a certain date.
Anybody out there to help me with this?
Thanks in advance
Kai
Change the set "searchterm=apple" to your search term
Alter these line to the dates you need
set oldest=2006-06-01
set newest=2006-12-31
Change the filespec in this line: "c:\files\*.txt"
#echo off
:: based upon code by Todd Vargo 2007
setlocal
set "searchterm=apple"
:: Set date range below in yyyy-mm-dd format or your local format.
set oldest=2006-06-01
set newest=2006-12-31
:: =================
set tmp1="%temp%.\dir.out"
:: Set any legal filespec desired below.
dir "c:\files\*.txt" /a-d/s/b >%tmp1%
:: ==================
set vbs="%temp%.\tmp.vbs"
type nul>%vbs%
call :vbs echo >>%vbs%
cscript /nologo %vbs% >"%temp%\filelist.tmp"
del %vbs%
del %tmp1%
for /f "usebackq delims=" %%a in ("%temp%\filelist.tmp") do (
findstr /i /c:"%searchterm%" "%%a" >nul && echo found "%searchterm%" in "%%a"
)
del "%temp%\filelist.tmp" 2>nul
pause
goto :eof
:vbs
%1 d1 = #%oldest%#
%1 d2 = #%newest%#
%1 Const ForReading = 1, ForWriting = 2
%1 'Wscript.Echo DateDiff("d", d1, d2)
%1 Set fso = CreateObject("Scripting.FileSystemObject")
%1 Set f = fso.OpenTextFile(%tmp1%, ForReading)
%1 count = 0
%1 Do Until f.AtEndOfStream
%1 s = f.ReadLine
%1 Set f1 = fso.GetFile(s)
%1 If d1 ^< DateValue(f1.DateCreated) and _
%1 DateValue(f1.DateCreated) ^< d2 Then
%1 Wscript.Echo f1.Path
%1 count = count + 1
%1 End If
%1 Loop
%1 ' Wscript.Echo " Total Files Listed:", count

batch - append either date/time of creation or random to end of filename

Damsel in distress needing help with a batch-script.
I have a bunch of files that one system creates. Either in one of 2 directories, or in the directory above that.
The naming is apparently not very important, so It's a bit random.
2 questions for you batch-geniuses out there.
a) How can I append date/time of creation to the end of the filename with a batch-script?
b) How can I append a random filename (so I make the files unique) with a batch-script?
Thanks in advance, dudes and dudettes.
Yours sincerely, the Maclovin!
I have decided in my wisdom to not give a sh*t about the date of creation. I gather it follows the file anyway. What I want to do instead, is to append todays date/time to the file.
This is what I have:
SetLocal EnableDelayedExpansion
set kvitt1="c:\a"
set kvitt2="c:\b"
set tmpDir="c:\temp"
set LASTMOD=
set DATO=%DATE%
set KLOKKE=%TIME%
pause
REM lets go to this directory, and scan for files, and copy to the temp
pushd %kvitt1%
:ONE
for /f "tokens=*" %%a in ('dir /b /od 2^>NUL') do set lastmod=%%a
if "%lastmod%"=="" echo Could not locate files.&goto :TWO
COPY "%Lastmod%" %tmpDir%
pause
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
popd
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
REM Let's go to the next directory, and scan for files to copy to the temp
:TWO
REM Gå til ny nettverksstasjon
pushd %kvitt2%
for /f "tokens=*" %%a in ('dir /b /od 2^>NUL') do set lastmod=%%a
if "%lastmod%"=="" echo Could not locate files.&goto :EOF
COPY "%LASTMOD%" %tmpDir%
pause
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
popd
REM we have copied the files we need, lets skip to the temp directory for renaming and filenaming
pushd %tmpDir%
echo %tmpDir%
pause
REM this is clearly not doing much.
REM gåsetegn foran tmpDir fordi det kan finnes filer med mellomrom. dir/b lister opp filene i mappen, og lagrer det i filelist.txt
dir /b "%tmpDir%" >>filelist.txt
pause
REM går igjennom alle linjene i fillist.txt. %%i inneholder filnavnet
pause
REM for /f %%i in (filelist.txt) do
REM (
REM This is clearly not working
for /F "tokens=2,3,4 delims=/ " %%a in ('date /t') do set filedate=%%a-%%b-%%c
ren %filedate%_"%%T" "%T"
REM ren "%%T" %!random%"%%~nT.kvi")
pause
Try this for a:
ECHO Making the copy...
COPY C:\file.txt c:\file_%time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%.txt
PAUSE
CLS
EXIT
The time parsing is done by (leave out the ECHO if using it within naming a file):
ECHO %time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%
I got this from http://www.ozzu.com/mswindows-forum/can-batch-files-use-date-for-filename-creation-t75600.html where theres a bit more details about it.
As for b, the time here records up to seconds so appending the time will make it unique unless your doing more than 1 per second.
EDIT: This gets only the current date. For the batch rename to file date try this instead:
for /f "delims=|" %%f in ('dir /b C:\temp') do call :runsub %%f
goto EOF
:runsub
set t=%~t1
set t=%t::=%
set t=%t: =%
set t=%t:/=%
set renameto=%~n1-%t%%~x1
Copy %1 %renameto%
:EOF
PAUSE
You can change C:\temp to the path you want to change the files in. Let me know if theres any changes you need.
you are better off using vbscript (or powershell if you have) , rather than batch. this is because date manipulation in batch is dependent on regional settings of your computer. You will have to use tricks like going into the registry and stuff as workaround.
Here's a vbscript you can adapt to your needs.
Set objFS = CreateObject( "Scripting.FileSystemObject" )
strFolder = WScript.Arguments(0)
Set objFolder = objFS.GetFolder(strFolder)
t = Now
strDate = Year(t) & Month(t) & Day(t) & Hour(t) & Minute(t) & Second(t)
' by random number
Randomize
upperbound = 99999
lowerbound = 55555
For Each strFile In objFolder.Files
strExtension = objFS.GetExtensionName( strFile )
strName = objFS.GetBaseName( strFile)
rand = Int((upperbound - lowerbound + 1) * Rnd + lowerbound) 'gen random number
' uncomment to use date
' strFile.Name = strName & strDate & "." & strExtension
' uncomment to use random number of your choosing
' strFile.Name = strName & rand & "." & strExtension
Next

Resources