0

I exported some mail files from an application and during the export the subject is taken as filename. However there are some files in source system without subject so the file name is also empty (only containing a space). I tried to run a Powershell script to fix all of these. However nothing happens:

Get-ChildItem <location> -recurse | ForEach-Object {if ($_.Name -Like " ") {Rename-Item "subject"}}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
Nick
  • 161
  • 1
  • 2
  • 14
  • 1
    the `.Name` property includes the extension. i think you want to test the `.BaseName` instead. – Lee_Dailey Feb 27 '19 at 12:28
  • I tried that as well, so how I define an empty file name is correct? It's a bit strange situation – Nick Feb 27 '19 at 12:30
  • Is it possible to check if filename is shorter than 1 or something? – Nick Feb 27 '19 at 12:33
  • you said the name was a single space. [*frown*] you can test that with `-eq ' '` or with `[string]::IsNullOrWhiteSpace($_.BaseName)`. – Lee_Dailey Feb 27 '19 at 12:47
  • @Lee_Dailey true, I also found a filename that was completely empty. ;) – Nick Feb 27 '19 at 13:11
  • ha! i can't make any such file names to test with, but the `[string]::IsNullOrWhiteSpace($_.BaseName)` should still work. [*grin*] – Lee_Dailey Feb 27 '19 at 13:16
  • @Lee_Dailey: Good point re `.BaseName`. On Windows you can only make an all-spaces filename / filename with trailing spaces if the filename also has an _extension_; e.g., `' .txt'` works, but just `' '` doesn't. – mklement0 Feb 27 '19 at 14:57

2 Answers2

0

I guess you are storing them as txt files. Then, use the code:

Get-ChildItem -recurse | ForEach-Object {if ($_.BaseName -Like " ") {Rename-Item " .txt" "subject.txt"}}

If the files have some other extension, replace .txt with your extension

  • Did the trick indeed! Thanks to @Lee_Dailey & Karun sajeev Get-ChildItem -recurse | ForEach-Object {if ([string]::IsNullOrWhiteSpace($_.BaseName)) {Rename-Item -Path $_.FullName -NewName ("subject" + $_.Extension)}} – Nick Feb 27 '19 at 13:41
0

Lee Daily provided the crucial pointer in a comment: the .Name property of the file-info objects output by Get-ChildItem includes the extension, whereas you must test just .BaseName, i.e. the part of the filename excluding the extension.

Get-ChildItem $someDir -Recurse | Where-Object BaseName -eq ' ' |
  Rename-Item -NewName { 'subject' + $_.Extension } -WhatIf

PSv3+ syntax; common parameter -WhatIf previews the renaming operation; remove it to perform actual renaming.

  • There is no point in using the -like operator if the pattern to compare against is a literal string such as ' ' - hence, -eq is used.

  • Note the use of a delay-bind script block with -NewName, which allows piping directly to Rename-Item, without the need for an intermediate - and inefficient - ForEach-Object call.

  • If the filenames can be composed of a variable number of spaces (one or more), use the following Where-Object call instead, which uses the -match operator with a regular expression:

    Where-Object BaseName -match '^ +$'
    
mklement0
  • 382,024
  • 64
  • 607
  • 775