Ex: doc_1.2.3.jar
Expected output: doc.jar
dir /b
for %%f in (*_*.jar) do call :ProcessFile %%f
goto :finished
:ProcessFile
set str=%1
rename %1 %str:_=%
goto :eof
:finished
echo ----
dir /b
I tried using wildcards, but it doesn't seem to work
rename %1 %str:_*.jar=.jar%
A way :
#echo off
for /f "tokens=1,2 delims=_" %%a in ('dir /b/a-d *.jar') do rename "%%a_%%b" "%%a.jar" 2>nul
Related
In my hard disk I have the following structure:
ROOTFOLDER
├───FOLDER1
│ └───TMPFOLDER
│ ├───FOLDERTODELETE1
│ ├───FOLDERTODELETE2
│ └───FOLDERTODELETE3
├───FOLDER2
│ └───TMPFOLDER
│ ├───FOLDERTODELETE4
│ └───FOLDERTODELETE5
└───FOLDER3
└───TMPFOLDER
├───FOLDERTODELETE6
├───FOLDERTODELETE7
└───FOLDERTODELETE8
I need to create a kind of script (I was thinking about a batch file, but any other solution will be appreciated) to delete all folders within each folders with a specific name (in this case TMPFOLDER) and created before today.
Following to your needs the batch script below will do what you need. Remove the echo in front of the rmdir command if it's okay for you. Take care that the script uses the current working directory. Remove /q if you want to be asked for each directory that should be deleted:
#echo off
set "tmpfolder=TMPFOLDER"
for /f "tokens=*" %%D in ('dir /b /a:d "*"') do (
for /f "tokens=*" %%E in ('dir /b /a:d "%%D\*" ^| findstr /l /x %tmpfolder%') do (
echo Found temp folder: "%%D\%%E"
for /f "tokens=*" %%F in ('dir /b /a:d "%%D\%%E\*"') do (
echo rmdir /s /q "%%D\%%E\%%F"
)
)
)
Edit #1:
The above script does not take care of the creation date of the folder that should be removed. You want only folders to be deleted which have a creation date before today. The following script takes care of that. Look here how to get dates of folder and here how to compare dates:
#echo off
setlocal EnableDelayedExpansion
set "tmpfolder=TMPFOLDER"
for /f "tokens=*" %%D in ('dir /b /a:d "*"') do (
for /f "tokens=*" %%E in ('dir /b /a:d "%%D\*" ^| findstr /x /c:"%tmpfolder%"') do (
rem echo Found temp folder: "%%D\%%E"
for /f "tokens=*" %%F in ('dir /b /a:d "%%D\%%E\*"') do (
rem echo Subfolder: "%%F"
set "curdate=!date!"
set "dirdate="
echo GETDATE
call :getdate dirdate "%%D\%%E\%%F"
set "dirdate=!dirdate:~-4!!dirdate:~3,2!!dirdate:~0,2!"
set "curdate=!curdate:~-4!!curdate:~3,2!!curdate:~0,2!"
rem echo dirdate: "!dirdate!"
rem echo curdate: "!curdate!"
rem echo.
if [!dirdate!] LSS [!curdate!] (
echo rmdir /s /q "%%D\%%E\%%F"
)
)
)
)
goto :EOF
:getdate
rem call: getdate date(dstParam) folder(srcParam)
for /f "skip=5 tokens=1 delims= " %%A in ('dir /a:d /o:d /t:c "%~2"') do (
set "%~1=%%A"
goto :EOF
)
Command reference links from ss64.com:
DelayedExpansion
set
for /f
dir
findstr
if
call
goto
rem
Although an answer has already been accepted, I have decided to post this untested idea as an alternative:
#Echo Off
SetLocal EnableDelayedExpansion
For /F "Delims=" %%A In ('WMIC OS Get LocalDateTime') Do For %%B In (%%~nA
) Do Set "TD=%%B" & Set "TD=!TD:~,8!"
For /D /R "ROOTFOLDER" %%A In ("TMPFOLD?R") Do If /I "%%~nxA"=="TMPFOLDER" (
Set "FP=%%~pA" & Set "FP=!FP:\=\\!"
WMIC FSDir Where "Path='!FP!' And FileName='TMPFOLDER'" Get CreationDate^
|FindStr/B "%TD%">Nul||Echo=RD/S/Q "%%A")
Timeout -1
You may need to change ROOTFOLDER and all instances of TMPFOLDER as necessary, remembering to use a ? to replace one of the characters in the first instance of TMPFOLDER.
If the output appears to be correct, remove the last line and Echo= from the line above it.
I have a folder with several subfolders. Structure is like:
C:\foo
C:\foo\web.foo
C:\foo\web.bar
C:\foo\win.foo
C:\foo\win.bar
C:\foo\mobile.foo
C:\foo\mobile.bar
I sometimes wish to delete the folders with its containing files with following batch script:
rmdir C:\foo /s /q
Here it didn't matter that the whole folder C:\foo was deleted completely.
But now I only want to delete only the subfolders of C:\foo with its containing files, which DO NOT start with "web.".
Do you have any good solution for this?
The following should do the trick, note it's a batch file using the current directory:
#echo off
for /F "delims=" %%D in ('dir /B /AD ^| findstr /V "^web."') do (
echo rmdir %%D /s /q
)
If it's okay remove the echo in front of rmdir.
The dir command just list directory names because of /AD and use a simple name output because of /B. To search on the beginning use findstr with /V. For negation use ^. Further the pipe symbol needs to be escaped ^|.
If you want a dynamic batch script that uses arguments you can use the following, call it via batchname.bat "C:\foo" web. (if it's okay remove the echo in front of rmdir.):
#echo off
set INVARGS=0
if [%1] == [] set "INVARGS=1"
if [%2] == [] set "INVARGS=1"
if %INVARGS% == 1 (
echo echo %0 ^<directory^> ^<directory_prefix^>
goto eof
)
set "folder=%1%"
set "prefix=%2%"
pushd "%folder%"
echo List of folders that should be deleted:
for /F "delims=" %%D in ('dir /B /AD ^| findstr /v "^%prefix%"') do (
echo "%cd%\%%D"
)
popd
:choice
echo.
set /P "c=Are you sure you want to continue [Y/N]?"
if /I "%c%" EQU "Y" goto yes
if /I "%c%" EQU "N" goto eof
goto :choice
:yes
echo.
pushd "%folder%"
for /F "delims=" %%D in ('dir /B /AD ^| findstr /v "^%prefix%"') do (
echo rmdir %%D /s /q
)
popd
:eof
This will remove all files begin with web.
#echo off
setlocal EnableDelayedExpansion
for /f %%F in ('dir /b /s') do (
set "name=%%~nF"
if /i not "!name:~0,4!" == "web." (
rm !name!
)
)
I want to traverse all files within a specific directory and all its subdirectories and then print out the folder name of each file.
I don't know how to get the folder name of each file.
FOR /F "delims=" %%x IN ('dir /B /A /S *') DO (
:: Suppose %%x is 'C:\myfolder\a.txt', the desired output is 'myfolder'
:: %%~nx is not correct
echo ???
)
If you want just the path (without drive, without filename), %%~px is what you need
If you want just the last folder, not the complete path. This is indeed not that trivial:
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%x in ('dir /b /a /s *') do (
set "line=%%~dpx"
for /f "delims=" %%y in ("!line:\=.!") do set folder=%%~xy
echo %%~nxx is in: !folder:~1!
)
I think this is what you're looking for:
#echo off
FOR /F "delims=" %%F IN ('dir /B /A /S *') DO (
for %%D in ("%%~dpF\.") do echo %%~nxD
)
pause
I am new to command prompt scripting and batch files. I have a folder with the following:
file1.pdf
file1.tif
file1_cropped.tif
file1.txt
file2.pdf
file2.tif
file2_cropped.tif
file2.txt...
filen.pdf
filen.tif
filen_cropped.tif
filen.txt
I would like to delete all the tif files that do not have "_cropped" in the filename. I have seen a few solutions for deleting files that have a specified extension, or that match a specific string, but I am trying to combine the two.
Much thanks,
Marc.
for /f "delims=" %%a in ('dir /b /a-d *.tif^|find /v /i "_cropped"') do echo del "%%a"
should suit.
perhaps you'd want
pushd "target directoryname"
for /f "delim...
popd
to specify a directory other than your current to be processed.
The required DEL commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO DEL to DEL to actually delete the files.
From command line, being in target directory:
for /F "eol=: delims=" %a in ('dir /b *.tif ^| find /V "_cropped"') do #del "%a"
Where we have:
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
In batch file:
for /F "eol=: delims=" %%a in ('dir /b *.tif ^| find /V "_cropped"') do #del "%%a"
A sample where we use a more interactive approach with confirmation:
Use typically as:
the_bat_file.bat exclude_these tif
Where option one is string in file names to exclude and two is file extension.
#echo off
set pat=_cropped
set ext=tif
IF "%1"=="--help" (
echo Usage %0 [exclude] [extension]
echo Default exclude : %pat%
echo Default extension: %ext%
goto end
)
GOTO part1
:confirm
SET /P CONF=Continue y/N?
IF /I "%CONF%" NEQ "Y" GOTO end
goto %con%
:part1
setlocal
IF NOT "%1"=="" set pat=%1
IF NOT "%2"=="" set ext=%2
echo Pattern : %pat%
echo Extension: %ext%
echo.
set con=part2
goto confirm
:part2
echo.
echo Files to delete:
echo.
for /F "eol=: delims=" %%a in ('dir /b "*.%ext%" ^| find /V "%pat%"') do echo "%%a"
echo.
set con=part3
goto confirm
:part3
for /F "eol=: delims=" %%a in ('dir /b "*.%ext%" ^| find /V "%pat%"') do DEL "%%a"
:end
endlocal
I can use this to loop over files:
for %%a in ("%directory%\*.%extension%") do (
echo FILE: %%~fa
)
goto :eof
What if I also rename the files, like this (:rename is a subroutine that renames the files):
for %%a in ("%directory%\*.%extension%") do (
echo FILE: %%~fa
call :rename "%%~fa"
)
goto :eof
In that case, some of the files are renamed (and echoed) two or even three times. I think it's because after they are renamed, in some cases they are regarded as new files that also need to be looped through. However, this does not happen with all the renamed files.
How can I overcome this? I want every file to be renamed only once.
Solution:
:: remove quotes:
:: http://www.dostips.com/?t=Snippets.TrimQuotes
for /f "useback tokens=*" %%a in ('%extension%') do set extension=%%~a
for /f "useback tokens=*" %%a in ('%directory%') do set directory=%%~a
for /f "delims=" %%a in ('dir /b /a-d "%directory%\*.%extension%" ^| sort /r') do (
echo FILE: %directory%\%%a
call :renamingSubroutine "%directory%\%%a"
)
goto :eof
OR:
:: remove quotes:
:: http://www.dostips.com/?t=Snippets.TrimQuotes
for /f "useback tokens=*" %%a in ('%extension%') do set extension=%%~a
for /f "useback tokens=*" %%a in ('%directory%') do set directory=%%~a
for /f "delims=" %%a in ('dir /b /a-d /s /on "%directory%\*.%extension%"') do (
echo FILE: %%~fa
call :renamingSubroutine "%%~fa"
)
goto :eof
try this:
for /f "delims=" %%a in ('dir /b /a-d /s "%directory%\*.%extension%"^|sort /r') do (
echo FILE: %%~fa
call :rename "%%~fa"
)
goto :eof
BTW you shouldn't give batch functions the names of cmd commands (rename).