I have a directory structure that reads like:
nnnnnn~substring
Where n are numbers, and substring are letters.
I am trying to write a batch file that tests if a particular file exists inside the directory, and if it does, it should rename the directory to substring.
The batch file should look like:
for /f "tokens=\*" %%a in ('dir /b') do if exist filename (rename nnnnnn~substring substring)
How do I trim all the numbers and the ~ character of the directory name so I can rename it using only the final part of the name?
The numbers before the ~ separator have different lengths, so does the substring after it.
#echo off
setlocal enableextensions disabledelayedexpansion
rem Change to the target folder
pushd "x:\somewhere" && (
rem For each folder inside it matching the indicated pattern
rem Uses a dir command to search only folders and a
rem findstr filter to ensure only matching folders
for /f "delims=" %%a in ('
dir /ad /b *~* ^| findstr /r /c:"^[0-9][0-9]*~..*$"
') do (
rem Check if the folder contains the file
if exist "%%~fa\flagFile.txt" (
rem Split the folder name using the ~ as delimiter
for /f "tokens=1,* delims=~" %%b in ("%%~na") do (
rem Check that the new folder name does not exist
if not exist "%%~c%%~xa" (
rem Execute the rename operation
echo ren "%%~fa" "%%~c%%~xa"
)
)
)
)
rem Restore previous active directory
popd
)
Rename operations are only echoed to console. If the output is correct, remove the echo that prefixes ren command
This may work - test it in a copy of your folder structure:
It assumes that substring in your question does not contain any ~ characters.
#echo off
:loop
for /d /r "d:\base\folder" %%a in (*~*) do (
if exist "%%a\filename" for /f "tokens=1,* delims=~" %%b in ("%%~nxa") do (
ren "%%a" "%%c"
goto :loop
)
)
pause
This is designed for only the folders within the current directory.
#echo off
for /d %%a in (*~*) do (
if exist "%%a\filename" for /f "tokens=1,* delims=~" %%b in ("%%~nxa") do ren "%%a" "%%c"
)
pause
Related
Need a bit of help with this script
for /d %%D in ("*") do (
for %%F in ("%%D\*.jpg") do (
ren "%%~dpF(*).txt" "(*) %%~nF.*"
)
)
This is the original script and this is what it does
Before
filename.jpg
(1).txt
Result
filename.jpg
(1) filename.txt
it copies the filename from the jpg and adds it to the filename of the txt file
what I have been trying to do is two things
I want to add a controlled Sub folder reader to it, and I would like to the filename to be copied between certain points of the txt files
Before
filename.jpg
(1)(name).txt
Result
filename.jpg
(1) filename (name).txt
I have tried like 10 different ways to make this work and for some reason I can't
tried this
FOR /f "delims=" %%q IN ('dir /b /s /a-d "Ready\(*)(Name).txt"') DO call :label "%%q"
goto :eof
:Label
set "FILE=%~1"
for /d %%D in ("*") do (
for %%F in ("%%D\*.jpg") do (
ren "%%~dpF(*)(Name).txt" "(*) %%~nF (*).*"
)
)
and I removed this as well for /d %%D in ("*") do (
and tried this
FOR /f "delims=" %%q IN ('dir /b /s /a-d "Ready\(*)(Name).txt"') DO call :label "%%q"
goto :eof
:Label
set "FILE=%~1"
for %%F in ("*.jpg") do (
ren "%%~dpF%~1" "(*) %%~nF (*).*"
)
and tried this
for /d %%D in ('dir /b /s /a-d "*"') do (
for %%F in ("%%D\*.jpg") do (
ren "%%~dpF(*)(Name).txt" "(*) %%~nF (*).*"
)
)
Any help would be great
Thank you
#ECHO OFF
SETLOCAL
rem The following setting for the source directory is a name which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
PUSHD "%sourcedir%"
for /d %%B in ("*") do (
for %%E in ("%%B\*.jpg") do (
FOR /f "tokens=1,2delims=()" %%q IN ('dir /b /a-d "%%~dpnxB\(*)(*).txt" 2^>nul') DO (
rem files matching "(*)(*).txt only
REN "%%~dpnxB\(%%q)(%%r).txt" "(%%q) %%~nE (%%r).txt"
)
FOR /f "tokens=1*delims=()" %%q IN ('dir /b /a-d "%%~dpnxB\(*).txt" 2^>nul') DO IF /i "%%r" equ ".txt" (
rem files matching "(*).txt only
REN "%%~dpnxB\(%%q).txt" "(%%q) %%~nE.txt"
)
)
)
popd
GOTO :EOF
Caution : This batch is armed. It will rename files. Always verify against a test directory before applying to real data.
The outer loop on %%B gets the directory names. No surprise there.
The next loop on %%E gets the .jpg names. No surprise there.
The first loop on %%q looks at the .txt files that fit the pattern (*)(*).txt and re-assembles the parts as required for the rename.
The second loop on %%q looks at the .txt files that fit the pattern (*).txt which may include the just-renamed files matching (*)(*).txt now (*) jpgfilename (*).txt, so this time, %%r must be .txt to exclude these newly-renamed files.
I'll repeat
Caution : This batch is armed. It will rename files. Always verify against a test directory before applying to real data.
I am new to writing batch programs. I have thousands of folders that have a leading space character in their name and I need to remove the space. By perusing the Stack Overflow site, I have put together some code that performs as expected in WinXP, but NOT on my Win10 system.
#echo off
for /d %%A in (" *") do #for /f "tokens=*" %%B in ("%%A") do #ren "%%A" "%%B"
The code snippet above works just fine in WinXP. For example, a folder may be named " L700" but the name gets correctly changed to "L700" after running the code. However, on my Win10 system, the above code doesn't change anything with the filename.
Full code is below:
#echo off
rem Prepare environment
setlocal enableextensions disabledelayedexpansion
rem configure where to start
set "root=C:\Test"
rem For each file under root that match indicated pattern
for /r "%root%" %%f in (*,*,*.xlsm) do (
rem Split the file name in tokens using the comma as delimiter
for /f "tokens=2 delims=," %%p in ("%%~nf") do (
rem Test if the file is in the correct place
for %%d in ("%%~dpf.") do if /i not "%%~p"=="%%~nd" (
rem if it is not, move it where it should be
if not exist "%%~dpf\%%~p" md "%%~dpf\%%~p"
move "%%~ff" "%%~dpf\%%~p"
)
)
)
rem line below removes space from beginning of folder name
for /d %%A in (" *") do #for /f "tokens=*" %%B in ("%%A") do #ren "%%A" "%%B"
#ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
FOR /d %%a IN ("%sourcedir%\ *") DO (
ECHO "%%a"
for /f "tokens=*" %%b in ("%%~nxa") do ECHO ren "%%a" "%%~nxb"
)
GOTO :EOF
ren command has been disarmed and is simply echoed for safety until script action is verified.
I've no access to an XP system, but I'm surprised it worked on XP. The issue is that %%a contains the full path so you need to select only the name and extension for the rename and the leading-space-suppression mechanism.
I am trying to move a list of .pdf files to folders based on the first 4 characters of said pdf files
#echo off
setlocal enabledelayedexpansion
for %%A in (*.pdf) do (
echo file found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=1* delims=_" %%D in ("!fname!") do set folname=%%D
echo folder name !folname!
if not exist "!folname!" (
echo Folder !folname! does not exist, creating
md "!folname!"
) else (
echo Folder !folname! exists
)
echo Moving file %%A to folder !folname!
move "%%A" "!folname!"
)
echo Finished
pause
To move all .pdf files in the current directory into directories named using the first four characters of their basename, here's a batch-file example, (without all of the unnecessary screen output):
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For %%A In (*.pdf)Do (Set "fN=%%~nA"
SetLocal EnableDelayedExpansion
RoboCopy . "!fN:~,4!" "%%A" /Mov>NUL
EndLocal)
EndLocal
GoTo :EOF
You could probably even do it as a single line command.
From a batch-file:
#For %%A In (*.pdf)Do #Set "fN=%%~nA"&Call RoboCopy . "%%fN:~,4%%" "%%A" /Mov>NUL
From a single cmd instance:
For %A In (*.pdf)Do #Set "fN=%~nA"&Call RoboCopy . "%fN:~,4%" "%A" /Mov>NUL
Please note that the ideas presented above assume that your .pdf basenames do not contain any exclamation marks/points and that Robocopy.exe exists in the current directory or within the locations specified under %PATH%.
Please also note that the 4th character in your basenames should not be a space or period, as the Windows shell and user interface does not support those.
I downloaded about 34000 books in .txt format from Project Gutenberg. Now I want to rename all of them by its content. For example every text file includes its "Title" and "Author's Name" so I want to rename all the text files on its "Title" and "Author's Name" by some commands.
I created a batch file. It runs but is not renaming the files. This is my code:
#echo off&setlocal
cd E:\Test
for /f "delims=" %%i in ('dir /a-d/b *.txt') do (
set "nname="
set "fname=%%~i"
for /f "usebackqskip=7delims=" %%f in ("%%~i") do if not defined nname
set "nname=%%f"
setlocal enabledelayedexpansion
set "nname=!nname:~0,40!"
echo rename "!fname!" "!nname!"
endlocal
)
You can use this as a base
#echo off
setlocal enableextensions disabledelayedexpansion
rem Change to source folder
pushd "e:\test" && (
rem Where the renamed files will be placed to avoid re-rename
if not exist renamed\ md renamed
rem For each input file
for %%f in (*.txt) do (
rem Retrieve the data from inside the file
set "author=" & set "title="
for /f "tokens=1,* delims=: " %%a in ('
findstr /b "Author: Title:" "%%~ff"
') do if not defined %%a set "%%a=%%b"
rem If the fields have been retrieved then do the rename
if defined author if defined title (
setlocal enabledelayedexpansion
for /f "delims=" %%a in ("!author! - !title!") do (
endlocal
echo move "%%~ff" "renamed\%%a%%~xf"
rem NOTE: operation is only echoed to console
rem if console output seems correct, then
rem remove the echo command
)
)
)
rem Done. Return to previous active directory
popd
)
Of course, filesystem has rules about what is allowed in a file name and, not knowing what kind of characters can be found, this code could and probably will fail to rename some files.
Your current script will just print the rename commands, not execute them. You should remove echo (after checking what it produces) in this line:
echo rename "!fname!" "!nname!"
Your script also has a few formatting issues. There should be spaces like this:
for /f "usebackq skip=7 delims=" %%f in ("%%~i") do
And there should be no newline just after:
if not defined nname
I need a command to run from the Windows CLI to identify any folders (or sub folders) that contain only one file. If the folder contains two files, it should not be included. In the end, I need to output this list to a text file. It should contain the full folder path.
Ex: OutputLog.txt
C:\fold1
C:\fold1\sub
C:\fold3
C:\fold4
This should work to identify folders with one file.
#echo off
for /d /r "d:\base\folder" %%a in (*) do (
dir /b /a-d "%%a" 2>nul |find /c /v "" |findstr "^1$" >nul && >>file.txt echo %%a
)
#echo off
setlocal EnableDelayedExpansion
(for /D /R %%a in (*) do (
set count=0
for %%b in ("%%a\*.*") do set /A count+=1
if !count! equ 1 echo %%a
)) > OutputLog.txt
#echo off
set "parentfolder=c:\test"
for /f "tokens=* delims=" %%F in ('dir /s /a:d /b "%parentfolder%"') do (
dir "%%F"|findstr /b "1 File(s)" >nul 2>&1 && echo %%F
)
This will list all subfolders with only one file in a parent folder .As it checks the string of the dir command output it should be altered if language settings/windows version provide different DIR command output.