Not getting expected function renaming files via batch script - batch-file

I have a script I've written to remove the first six characters and then replace the beginning of the filename with the parent folders name. It currently seems to work, but then continues cutting 6 characters at a time till nothing is left, then adds the parent name. Don't know how I can fix this.
Files are currently named SF-1.1~~~~~~~~.pdf , SF-2.3~~~~~~~.pdf, etc and I just want to remove that SF string including the numbers. The rename command hated the period so I have the code prior to the rename removing any periods other than the extension and making them spaces.
set mypath=%cd%
echo %mypath% (where %mypath% is the current directory that the batch file is sitting in)
for %%a in ("%~dp0\.") do set "parent=%%~nxa"
rem echo %parent%
setlocal enableextensions disabledelayedexpansion
set "root=%cd%"
for /r "%root%" %%a in ("*.?*.pdf") do (
set "filename=%%~na"
setlocal enabledelayedexpansion
for %%f in ("!filename:.= !") do (
endlocal
ren "%%~fa" "%%~f%%~xa"
)
)
del root
dir /b *.pdf > temp
for /f "delims=" %%a in (temp) do rename "*.pdf" "//////*.pdf"
del temp
dir /b *.pdf > temp
for /f "delims=" %%a in (temp) do ren "%%a" "%parent% %%a"
del temp

Related

Trying to get some script to move a pdf file into a folder based on first 4 characters of filename

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.

Renaming .txt files in bulk

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

cmd.exe batch to crop dirname

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

Batch only show directorys and their subdirectorys

I am having an question
How can i loop through an folder and only show folders and their subfolders without the full path.
example
if i use dir /b /s /ad
i will see e:\Mainfolder\Folder1\Subfolder
And i only whant to see
Folder1\Subfolder
the reason i want it is so i can put it inside an txt field and then with another loop check if the folder/subfolder exist somewhere else if not then it needs to create it.
With kind regards,
Thomas de Vries
#echo off
setlocal enableextensions disabledelayedexpansion
set "startingFolder=%cd%"
:: Determine the length of the starting path to remove
:: it from output
for /d %%a in ("%startingFolder%\"
) do for /f "skip=1 tokens=1 delims=:" %%b in (
'(echo(%%~fa^&echo(^)^|findstr /o "^"'
) do set /a "cutPoint=%%b-3"
:: Recurse folders from starting point and echo the
:: full path without the starting folder
for /r "%startingFolder%" /d %%a in (*) do (
set "line=%%a"
setlocal enabledelayedexpansion
echo(!line:~%cutPoint%!
endlocal
)
This will recurse over the tree structure, starting at the indicated folder (change startingFolder variable to what you need). For each folder found its relative path is echoed to console. Redirect output of batch to generate the required .txt file
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in ('dir /b /s /ad') do (
set "name=%%a"
echo !name:*e:\Mainfolder\=!
)

Unflattening a directory structure based on filenames

This is the inverse of the "flatten" operation described in this question: Flattening a directory
I would like a batch script that will go through each file in a "flattened" directory and put them back into their original directories, creating the directories as necessary
So if the following files were in my folder:
images-nature-dcim001.jpg
images-nature-dcim002.jpg
images-dcim003.jpg
images-indoors-dcim004.jpg
It would produce the resulting directory structure, creating the directories and moving (or copying) the files into the correct folder.
images
dcim003.jpg
nature
dcim001.jpg
dcim002.jpg
indoors
dcim004.jpg
Note: the example uses hyphens to separate the directories, but they can be any character.
This works here. It creates the four files at the top and then moves them.
#echo off
type nul >images-nature-dcim001.jpg
type nul >images-nature-dcim002.jpg
type nul >images-dcim003.jpg
type nul >images-indoors-dcim004.jpg
for %%a in (*.jpg) do call :routine "%%a"
pause
goto :eof
:routine
set "a=%~1"
set "b=%a:-=\%"
for %%b in ("%b%") do (
md "%%~pb" 2>nul
move "%a%" "%%~pb\%%~nxb"
)
#ECHO OFF &SETLOCAL
FOR /f "delims=" %%a IN ("%cd%") DO SET "precur=%%~dpa"
FOR /f "delims=" %%a IN ('dir /b /s /a-d *.txt') DO (
SET "fname=%%~fa"
SETLOCAL ENABLEDELAYEDEXPANSION
SET "nname=!fname:%precur%=!"
SET "nname=!nname:\=-!"
ECHO REN "!fname!" "!nname!"
ENDLOCAL
)
Here's the version I am using based on foxidrive's approach to getting the directory name. I didn't think of simply replacing delimiters with back-slashes.
#echo off
Setlocal EnableDelayedExpansion
rem // Directory Unflatten
rem // recursively unflattens directories
rem // and prepends the directory name to
rem // the filename
rem // Configuration options
rem // * Files to search for
set pattern=*jpg;*.png
rem // * Directory name delimiter
set delim=-
rem // Perform moving
for %%X in (%pattern%) do (
set A=%%X
rem // Replace delimiter with back-slash
set b=!A:%delim%=\!
rem // Not sure how to clean this up
for %%B in ("!b!") do (
if not exist %%~pB (
md "%%~dpB"
)
move "!A!" "%%~dpB%%~nxB"
)
)

Resources