Home > Blockchain >  Remove last 4 characters of a file in a folder with a batch file
Remove last 4 characters of a file in a folder with a batch file

Time:04-25

this should be pretty simple, i just want a bat file that when placed in a folder will rename all files within the folder and delete the final 4 characters, but not the extension

ex.

img (1).jpg

becomes

img.jpg

ive tried

@echo off
setlocal enabledelayedexpansion
if not exist %1 goto :eof
for /f %%A in ('find /V /C "" ^<%1') do set lines=%%A
for /f "tokens=1,* delims=[]" %%A in ('find /V /N "" ^<%1') do (
if %%A LSS %lines% (
echo %%B
) else (
set rec=%%B
echo !rec:~0,-4!
)
)

but it doesnt work. theres no error, it runs, it just doesnt do anything

CodePudding user response:

The file renaming task for all *.jpg and *.jpeg files in the current directory of which file name ends with a space and a single digit number in round brackets can be done with a batch file with following command lines:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir "* (?).jpg" "* (?).jpeg" /A-D /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R /C:" ([0123456789])\.jpe*g$"') do (
    set "FileName=%%~nI"
    setlocal EnableDelayedExpansion
    ren "!FileName!%%~xI" "!FileName:~0,-4!%%~xI"
    endlocal
)
endlocal

That code works also for image file names containing one or more exclamation marks and one or more round brackets before the last four characters in file name to remove.

Note: The command REN outputs an error message if the current directory contains the two files photo (1).jpg and photo (2).jpg on renaming the second file to photo.jpg because of this is not possible after first file already renamed to photo.jpg. There cannot be two files with same name in same directory.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • ren /?
  • set /?
  • setlocal /?

Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul and |. The redirection operators > and | must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line in a separate command process started in background.

CodePudding user response:

I modified your code as follows:

1/ switched to a test directory (PUSHD testdirectoryname) and back (POPD)
2/ changed the %1 to a fixed filename
3/ Inserted some debug lines

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following setting for the source directory includes 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%"

if not exist q71992787.txt goto :eof
TYPE "%sourcedir%\q71992787.txt"
for /f %%A in ('find /V /C "" ^<q71992787.txt') do set lines=%%A
SET li
find /V /N "" <q71992787.txt
for /f "tokens=1,* delims=[]" %%A in ('find /V /N "" ^<q71992787.txt') do (
 if %%A LSS %lines% (
  echo %%B
 ) else (
  set rec=%%B
  echo !rec:~0,-4!
 )
)

POPD

GOTO :EOF

The result, other than the debug lines, was a list of the filenames in the file q71992787.txt, other than the very last filename, which was shortened by 4 characters.

This differs from your result "it just doesnt do anything". This is why I mention it.

So - to your solution:

I can see no reason for calculating the number of lines in the file. If there are 10 lines for example, then reading the same file again with 'find /v /n` will still find 10 lines.

The if %%A LSS %lines% will echo %%B (the filename) if %%A (the line number) is LESS (LSS) than 10; that is, from 1 to 9 - just show the filename.

The else clause will only be processed if %%A is 10 or greater, so only on the last line.

I'm sure this wasn't what you intended to do.

I'd advise you to use set "var1=value" for setting STRING values - this avoids problems caused by trailing spaces. Quotes are not needed for setting arithmetic values (set /a`)

Where you alter your filename, setting rec to %%B means the entire filename, %%B. You don't show us a sample from the file %1, so I'll presume it's img (1).jpg as your narrative mentions. rec will thus become img (1).jpg and then be shortened to img (1) by removing the last 4 characters of the string.

Since you seem to want to remove the last 4 characters of the name part and leave the extension, then you need to read the documentation for for (for /? from the prompt) which will tell you

set "rec=%%~nB"

will assign just the name part and you could then

set "rec=!rec:~0,-4!%%~xB"

echo !rec:~0,-4!%%~xB

to set or show the manipulated name.

As to why you get no result at all; This could be because the file encoding of %1 is unicode or is *nix format (, not line endings)

And I do hope you're not using a *nix emulator like cygwin where find becomes a file-locator, not a string-analyser.

CodePudding user response:

Doing it in PowerShell would be much easier

 ls *.jpg |% { ren $_ -ne ($_.BaseName.Substring(0, $_.BaseName.Length - 4)   $_.Extension) -wi }

-wi or -WhatIf is the option for dry running. After checking that the new names are OK you can remove that option. Full command line without alias:

Get-ChildItem -File *.* | ForEach-Object { Rename-Item -WhatIf -Path $_ `
    -NewName ($_.BaseName.Substring(0, $_.BaseName.Length - 4)   $_.Extension) }
  • Related