Remove extraneous characters from file name

I was tasked with taking a file repository a little overhead and removing the extra trash characters from the filename and saving the renamed file in a different directory folder.

File name example:

100-expresstoll.pdf
1000-2012-09-29.jpg
10000-2014-01-15_14.03.22.jpg
10001-2014-01-15_19.05.24.jpg
10002-2014-01-15_21.30.23.jpg
10003-2014-01-16_07.33.54.jpg
10004-2014-01-16_13.33.21.jpg
10005-Feb 4, 2014.jpeg
10006-O'Reilly_Media, _Inc..pdf

The first group of numbers at the beginning are record IDs and should be saved with the file extension. Anything else between the record IDs and the file extension needs to be dropped.

For example, the final name for the first three files would be:

100.pdf
1000.jpg
10000.jpg

I've read Deleting Characters and Editing Filenames in addition to other posts, but the complexity of the variable character length in front, the variable number of intermediate characters to be removed, and the variable file extension types really threw this outside of my limited PowerShell coverage.

+3


source to share


4 answers


Another approach without regex. Both of the following examples use the risk mitigation option -WhatIf

for debugging purposes.

Rename files:

Get-ChildItem -File | ForEach-Object {
    $oldFile = $_.FullName
    $newName = $_.BaseName.Split('-')[0] + $_.Extension
    if ($_.Name -ne $newName) {
        Rename-Item -Path $oldFile -NewName $newName -WhatIf
    }
}

      



Rename and move files:

$newDest = 'D:\test'                       ### change to fit your circumstances
Get-ChildItem -File | ForEach-Object {
    $oldFile = $_.FullName
    $newName = $_.BaseName.Split('-')[0] + $_.Extension
    $newFile = Join-Path -Path $newDest -ChildPath $newName
    if ( -not ( Test-Path -Path $newFile ) ) {
        Move-Item -Path $oldFile -Destination $newFile -WhatIf
    }
}

      

+3


source


You can use -replace

to perform this kind of string manipulation:

Get-ChildItem | foreach {

    $old_name = $_.FullName
    $new_name = $_.Name -replace '([0-9]+).*(\.[^.]*)$', '$1$2'

    Rename-Item $old_name $new_name
}

      

Regular expression is the trick:



  • ([0-9]+)

    means match a series of digits (1 or more digits)
  • .*

    means meeting all
  • (\.[^.]*)

    means period match followed by any non-period characters
  • $

    means that the match must go to the end of the line

The first and third are special because they are surrounded by parentheses, which means you can use those values ​​using dollar notation (for example $1

) in the replacement string.

+2


source


Probably the most idiomatic way to solve this is as follows (assuming all files of interest - and others - are in the current directory):

Get-ChildItem -File | Rename-Item -NewName { ($_.BaseName -split '-')[0] + $_.Extension }

      

Add a general parameter -WhatIf

to the command Rename-Item

to view the rename operation.

Note that it Rename-Item

always renames items at their current location; to (also) move them, use Move-Item

.

If a target with the same name already exists, Rename-Item

reports a fatal error for each such case (without interrupting general processing).
Note that it can also happen if the input file name does not contain -

, as this will attempt to rename the file to itself.

Explanation:

  • Get-ChildItem -File

    prints [System.IO.FileInfo]

    objects representing files in the current directory that are piped ( |

    ) to Rename-Item

    .

  • Passing a script ( { ... }

    ) block to Rename-Item

    -NewName

    execute executable code for each input object, where it $_

    represents the input object at hand.

    • Note that this almost undocumented but commonly used method is called the script -block [value] parameter, where the parameter that is for the pipeline input can be linked to the script block that indirectly handles the input.
  • ($_.BaseName -split '-')[0]

    -

    Retrieves the 1st segment token from each basename of the input filename (filename without extension).

  • +

    since LHS is a string, it does string concatenation.

  • $_.Extension

    extracts the filename extension from each input file name.

+2


source


I know this is not a PowerShell thing. If you just want something to work, this is the cmd batch file.

SETLOCAL ENABLEDELAYEDEXPANSION

SET "OLDDIR=C:\Users\lit\files"
SET "NEWDIR=C:\Users\lit\newdir"

FOR /F "usebackq tokens=*" %%a IN (`DIR /A:-D /B "%OLDDIR%\*"`) DO (
    FOR /F "usebackq delims=- tokens=1" %%b IN (`ECHO %%a`) DO (SET "BN=%%b")
    SET "EXT=%%~xa"
    ECHO COPY /Y "%OLDDIR%\%%~a" "%NEWDIR%\!BN!!EXT!"
)

      

0


source







All Articles