Batch Remove Substring from Filename with Special Characters in Bash

Batch remove substring from filename with special characters in BASH

Try this in your mv command:

mv "$f" "${f/.so/}"

First match of .so is being replaced by empty string.

Is there any way to remove specific characters from a filename in Windows, using a batch file?

You don't need to read the filename character by character. In batch you can simply replace all occurrences of a substring subs with another substring repl in the value of a variable %var% with %var:subs=repl%. As removing is the same as replacing with an empty string (in batch at least), %var:h=% will remove all hs from the value of the var variable. So all you need is to store the filename in a variable and you can have the new filename without [ and/or ].

To iterate over all files in a directory you'll just need a FOR loop.

So you can iterate over all files in the current directory and rename the ones with [ or ] in their name (or both) with the following script (see edit for version which also handles names with exclamation marks):

@echo off
Setlocal EnableDelayedExpansion

FOR %%G IN (*) DO (
set "filename=%%~G"
set "filename=!filename:[=!"
set "filename=!filename:]=!"
REM Rename only if there is a difference between new filename and old filename in %%G
IF NOT "!filename!" == "%%~G" ren "%%~G" "!filename!"
)
EndLocal
exit /b 0

Because the filename variable is set inside the FOR block and we want to read it inside the same block, we need delayed expansion.

EDIT: As @dbenham said in comment, delayed expansion can cause problems when you have filenames containing exclamation marks ! (%%~G will then contain a ! which normally announces a variable being expanded with delayed expansion). To solve that problem, @dbenham proposed a nice solution: enable delayed expansion only when we're about to use it i.e. inside the FOR block, just before using the filename variable. The ! won't poisin the value of a variable expanded with delayed expansion so !filename! can be used without a ! being misinterpreted in its value. This also means we'll have to move EndLocal to after we're done using delayed expansion in the FOR block (i.e. at the end of the block) and avoid the use of %%~G in the ren command. The latter can be done by using a variable to hold the original name (also before enabling delayed expansion) and use delayed expansion to retrieve the original name. That variable can then actually be used to construct the new filename.

@echo off

FOR %%G IN (*) DO (
REM Set filename without delayed expansion, no misinterpreted '!' possible
set "old_filename=%%~G"
REM before using old_filename, enable delayed expansion
SetLocal EnableDelayedExpansion
set "new_filename=!old_filename:[=!"
set "new_filename=!new_filename:]=!"
REM Rename only if there is a difference between new filename and old filename in %%G
ren "!old_filename!" "!new_filename!"
REM No more delayed expansion needed in block now
EndLocal
)

exit /b 0

Also, @KlitosKyriacou pointed out the IF was actually unnecessary: renaming a file with its original filename causes no harm. I've left it out in my 2nd version (the edit-version).

Find and replace a string with special characters using a batch file

Download JREPL.BAT written by Dave Benham which is a batch file / JScript hybrid to run a regular expression replace on a file using JScript and store it in same directory as the batch file below.

@echo off
call "%~dp0jrepl.bat" "file filename=\x22fffff" "network ipAdress=\x22172.24.55.32\x22 networkPort=\x229100" /XSEQ /F BCPrint.XML /O -

\x22 is " specified in hexadecimal form as an argument string can't contain a double quote character.

Batch script remove everything after a dynamic text from the string/filename

No need to specify the extension - it's still in the name.

Use a for /f to split at the first underscore.

:restoreFile
Set "FileName="
For /f "tokens=1* delims=_" %%N in ("%~1") Do Set "FileName=%%N"
If defined FileName Echo Ren %1 %FileName%
Goto :Eof

You may even put the date_time in front of the extension and so avoid possible dupes:

:restoreFile
Set "FileName="
For /f "tokens=1* delims=_" %%N in ("%~1") Do Set "FileName=%%~nN_%%M%%~xN"
If defined FileName Echo Ren %1 %FileName%
Goto :Eof

The ren commands are prepended with an echo, if the output looks OK remove the echo.

Replace or delete certain characters from filenames of all files in a folder

Use PowerShell to do anything smarter for a DOS prompt. Here, I've shown how to batch rename all the files and directories in the current directory that contain spaces by replacing them with _ underscores.

Dir |
Rename-Item -NewName { $_.Name -replace " ","_" }

EDIT :
Optionally, the Where-Object command can be used to filter out ineligible objects for the successive cmdlet (command-let). The following are some examples to illustrate the flexibility it can afford you:

  • To skip any document files

    Dir |
    Where-Object { $_.Name -notmatch "\.(doc|xls|ppt)x?$" } |
    Rename-Item -NewName { $_.Name -replace " ","_" }
  • To process only directories (pre-3.0 version)

    Dir |
    Where-Object { $_.Mode -match "^d" } |
    Rename-Item -NewName { $_.Name -replace " ","_" }

    PowerShell v3.0 introduced new Dir flags. You can also use Dir -Directory there.

  • To skip any files already containing an underscore (or some other character)

    Dir |
    Where-Object { -not $_.Name.Contains("_") } |
    Rename-Item -NewName { $_.Name -replace " ","_" }

Script to remove special characters from filenames

I've quickly thrown that together and didn't test it, but this VBScript should do the trick. Tell me if you need fancy stuff like folder recursive replacing etc.

Set objFSO = CreateObject("Scripting.FileSystemObject")

'Your folder here
objStartFolder = "X:\MYFOLDER"

Set objFolder = objFSO.GetFolder(objStartFolder)
Set regEx = New RegExp

'Your pattern here
regEx.Pattern = "[&%]"

Set colFiles = objFolder.Files
For Each objFile in colFiles
objFile.Rename(regEx.Replace(objFile.Name, "")
Next

Is it possible to manipulate filename in batch?

As you confirmed that this SET is inside for loop you'll need delayed expansion

setlocal enableDelayedExpansion

for %%G in (something) do (
set PL=%%~nG
set PL=!PL:~0,6!
echo !PL!
)


Related Topics



Leave a reply



Submit