DonationCoder.com forum
 
Read-only archive. This is a static copy of the DonationCoder.com forum. Reading and searching work as before; logging in, posting and private messages do not.
Archive of 2026-10-21 · About this archive · Main site

Author Topic: IDEA: Like FileSieve but folders have first two letters of file  (Read 8,486 times)

tabzilla

  • Participant
  • Joined in 2019
  • *
  • Posts: 13
FileSieve is a program which puts files into folders named after the first letter of the filename, e.g.,

Abani, Chris - Song for Night
Bach, Richard - Jonathan Livingston Seagull
Caldwell, June - Room Little Darker

becomes

A > Abani, Chris - Song for Night
B > Bach, Richard - Jonathan Livingston Seagull
C > Caldwell, June - Room Little Darker

but if say your S folder still has dozens/hundreds/thousands of files, it would be beneficial to be able to put them in folders named after the first two letters of the file, e.g.,

Sansom, William - The Body
Saravia, Alejandro - Red, Yellow and Green
satyal, rakesh - blue boy
Sloan, Holly Goldberg - Counting By 7s
Sloss, Aria Beth - Autobiography of Us
Slouka, Mark - Brewster
Swartwood, Robert - Hint Fiction
Sweeney, Kate - The O'Malley Legacy
Swift, Graham - Shuttlecock

becomes

SA > Sansom, William - The Body
SA > Saravia, Alejandro - Red, Yellow and Green
SA > Satyal, Rakesh - Blue Boy
SL > Sloan, Holly Goldberg - Counting By 7s
SL > Sloss, Aria Beth - Autobiography of Us
SL > Slouka, Mark - Brewster
SW > Swartwood, Robert - Hint Fiction
SW > Sweeney, Kate - The O'Malley Legacy
SW > Swift, Graham - Shuttlecock

FileSieve doesn't seem to do that and I've been unable to find any program which does.  So far I've been doing it by using Bulk Rename Utility to remove the first letter before using FileSieve then putting it back on with BRU after.

Many thanks.

Nod5

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 1,175
    • Coding Snacks
    • Participated in NANY Challenge Three Times
    • Plugin Coding Medal
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #1 on: October 08, 2019, 09:37 AM »
This should do it.

Code: ( autohotkey)
#NoEnv
SetWorkingDir %A_ScriptDir%
#SingleInstance force

;AutoHotkey script to move files into subfolders named after the filename's first two characters
;by Nod5 2019-10-08

;How to use:
;0. install https://www.autohotkey.com/ 
;1. edit the next line with a path to the files folder. For example "C:\folder\S"
folder := ""
;2. save the script with .ahk extension and UTF-8 BOM encoding and run it

;Check that the folder exists
If !InStr( FileExist(folder), "D")
  ExitApp

Loop, Files, %folder%\*.*
{
  tooltip `n Moving files into subfolders ...

  ;get filename's first two characters as uppercase
  two_chars := SubStr(A_LoopFileName, 1, 2)
  two_chars := Format("{:U}", two_chars)

  ;create subfolder if not already exists
  If !FileExist(folder "\" two_chars)
    FileCreateDir % folder "\" two_chars

  ;move file to subfolder
  FileMove, % A_LoopFilePath, % folder "\" two_chars
}
ExitApp


In addition another script to generate a bunch of empty text files for testing/troubleshooting the above script

Code: ( autohotkey)
#NoEnv
SetWorkingDir %A_ScriptDir%
#SingleInstance force

;AutoHotkey script to generate 75 empty text files named with the format
;sa_1.txt , sa_2.txt , sa_3.txt , sb_1.txt ... 

chars := "abcdefghijklmnopqrstuvxyz"
test_folder := A_ScriptDir "\" A_Now
FileCreateDir, % test_folder
Loop, Parse, chars
  Loop, 3
    FileAppend,, % test_folder "\s" A_LoopField "_" A_Index ".txt"
ExitApp
« Last Edit: October 08, 2019, 08:06 PM by Nod5 »

tabzilla

  • Participant
  • Joined in 2019
  • *
  • Posts: 13
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #2 on: October 08, 2019, 09:50 AM »
It's working perfectly.  Thank you very much.
« Last Edit: October 09, 2019, 08:23 AM by tabzilla »

tabzilla

  • Participant
  • Joined in 2019
  • *
  • Posts: 13
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #3 on: October 10, 2019, 07:27 PM »
If you wanted to name the folders after everything before " - ", e.g.,

Achebe, Chinua - There Was a Country
Achebe, Chinua - Things Fall Apart
Adiga, Aravind - Last Man in Tower
Adiga, Aravind - The White Tiger
Alger, Horatio - Bound to Rise
Alger, Horatio - Driven From Home

becoming

Achebe, Chinua > Achebe, Chinua - There Was a Country
Achebe, Chinua > Achebe, Chinua - Things Fall Apart
Adiga, Aravind > Adiga, Aravind - Last Man in Tower
Adiga, Aravind > Adiga, Aravind - The White Tiger
Alger, Horatio > Alger, Horatio - Bound to Rise
Alger, Horatio > Alger, Horatio - Driven From Home

would that be a matter of modifying the above script or is it more complicated than that?

Thanks again.

tabzilla

  • Participant
  • Joined in 2019
  • *
  • Posts: 13
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #4 on: October 10, 2019, 08:37 PM »
I figured out how to change the folder names to the first three characters or first single character but incorporating a regex or anything was beyond me from just looking at other examples.

tabzilla

  • Participant
  • Joined in 2019
  • *
  • Posts: 13
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #5 on: October 11, 2019, 07:32 PM »
I've found a script that works for that here:

https://autohotkey.com/board/topic/61066-create-a-folder-for-each-file-in-a-directory/

I just had to change the extension to txt (I'm working with text files) and the regex to "\ - .*"

Sorry if it was bad etiquette to crowbar in a second request.

Nod5

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 1,175
    • Coding Snacks
    • Participated in NANY Challenge Three Times
    • Plugin Coding Medal
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #6 on: October 12, 2019, 08:34 AM »
No problem.

I made a version of my previous script to use the string before " - " in the filename as subfolder name. Just in case someone comes here via Google looking for a complete script for that.

The script can also be easily adapted to use some other pattern by changing only the regular expression line.


Code: ( autohotkey)
#NoEnv
SetWorkingDir %A_ScriptDir%
#SingleInstance force
 
;AutoHotkey script to move files into subfolders named after the string before " - " in the filename
;Example: the file "Lastname, Firstname - Title.txt" is moved to subfolder "Lastname, Firstname"
;by Nod5 2019-10-12
 
;How to use:
;0. install https://www.autohotkey.com/ 
;1. edit the next line with a path to the files folder. For example "C:\folder\S"
folder := ""
;2. save the script with .ahk extension and UTF-8 BOM encoding and run it
 
;Check that the folder exists
If !InStr( FileExist(folder), "D")
  ExitApp
 
Loop, Files, %folder%\*.*
{
  tooltip `n Moving files into subfolders ...
 
  ;get string before " - " in filename
  pattern := RegExReplace(A_LoopFileName, " - .*", "")
 
  ;create subfolder if not already exists
  If !FileExist(folder "\" pattern)
    FileCreateDir % folder "\" pattern
 
  ;move file to subfolder
  FileMove, % A_LoopFilePath, % folder "\" pattern
}
ExitApp

tabzilla

  • Participant
  • Joined in 2019
  • *
  • Posts: 13
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #7 on: October 13, 2019, 10:23 AM »
Much appreciated.

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #8 on: October 14, 2019, 07:05 AM »
Cheap and nasty PowerShell alternative :D

2019-10-14 17_58_15-Refile.png

Run it from the shortcut or a PowerShell console.

Entering a value for Separator overrides Use first x characters.

Disclaimer: Works here ;)

Code: ( powershell)
<# This form was created using POSHGUI.com  a free online gui designer for PowerShell
.NAME
    Refile.ps1
#>

Function FileBrowser {
  $objForm = New-Object System.Windows.Forms.FolderBrowserDialog
  $objForm.Description = "Select folder containing files"
  $objForm.SelectedPath = [System.Environment+SpecialFolder]'MyComputer'
  $objForm.ShowNewFolderButton = $false
  $result = $objForm.ShowDialog()
  if ($result -eq "OK") {
    return $objForm.SelectedPath
  } else {
    return ""
  }
}

#region begin GUI{ 

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form                            = New-Object system.Windows.Forms.Form
$Form.ClientSize                 = '400,350'
$Form.text                       = "Refile"
$Form.TopMost                    = $false

$TextBox1                        = New-Object system.Windows.Forms.TextBox
$TextBox1.multiline              = $false
$TextBox1.width                  = 225
$TextBox1.height                 = 21
$TextBox1.location               = New-Object System.Drawing.Point(85,19)
$TextBox1.Font                   = 'Microsoft Sans Serif,12'

$TextBox2                        = New-Object system.Windows.Forms.TextBox
$TextBox2.multiline              = $false
$TextBox2.width                  = 225
$TextBox2.height                 = 21
$TextBox2.location               = New-Object System.Drawing.Point(85,60)
$TextBox2.Font                   = 'Microsoft Sans Serif,12'

$Button1                         = New-Object system.Windows.Forms.Button
$Button1.text                    = "..."
$Button1.width                   = 40
$Button1.height                  = 30
$Button1.location                = New-Object System.Drawing.Point(323,17)
$Button1.Font                    = 'Microsoft Sans Serif,12'

$Button2                         = New-Object system.Windows.Forms.Button
$Button2.text                    = "..."
$Button2.width                   = 40
$Button2.height                  = 30
$Button2.location                = New-Object System.Drawing.Point(323,58)
$Button2.Font                    = 'Microsoft Sans Serif,12'

$Label1                          = New-Object system.Windows.Forms.Label
$Label1.text                     = "Source:"
$Label1.AutoSize                 = $true
$Label1.width                    = 25
$Label1.height                   = 10
$Label1.location                 = New-Object System.Drawing.Point(20,19)
$Label1.Font                     = 'Microsoft Sans Serif,12'

$Label2                          = New-Object system.Windows.Forms.Label
$Label2.text                     = "Dest:"
$Label2.AutoSize                 = $true
$Label2.width                    = 25
$Label2.height                   = 10
$Label2.location                 = New-Object System.Drawing.Point(20,59)
$Label2.Font                     = 'Microsoft Sans Serif,12'

$ComboBox1                       = New-Object system.Windows.Forms.ComboBox
$ComboBox1.width                 = 80
$ComboBox1.height                = 20
@('1','2','3','4','5') | ForEach-Object {[void] $ComboBox1.Items.Add($_)}
$ComboBox1.location              = New-Object System.Drawing.Point(230,190)
$ComboBox1.Font                  = 'Microsoft Sans Serif,12'

$Label3                          = New-Object system.Windows.Forms.Label
$Label3.text                     = "Use first x characters:"
$Label3.AutoSize                 = $true
$Label3.width                    = 25
$Label3.height                   = 10
$Label3.location                 = New-Object System.Drawing.Point(60,193)
$Label3.Font                     = 'Microsoft Sans Serif,12'

$Label4                          = New-Object system.Windows.Forms.Label
$Label4.text                     = "or"
$Label4.AutoSize                 = $true
$Label4.width                    = 25
$Label4.height                   = 10
$Label4.location                 = New-Object System.Drawing.Point(188,160)
$Label4.Font                     = 'Microsoft Sans Serif,12'

$TextBox3                        = New-Object system.Windows.Forms.TextBox
$TextBox3.multiline              = $false
$TextBox3.width                  = 80
$TextBox3.height                 = 20
$TextBox3.Text                   = ''
$TextBox3.location               = New-Object System.Drawing.Point(230,130)
$TextBox3.Font                   = 'Microsoft Sans Serif,12'

$TextBox4                        = New-Object system.Windows.Forms.TextBox
$TextBox4.multiline              = $false
$TextBox4.width                  = 80
$TextBox4.height                 = 20
$TextBox4.Text                   = 'txt'
$TextBox4.location               = New-Object System.Drawing.Point(230,95)
$TextBox4.Font                   = 'Microsoft Sans Serif,12'

$Label5                          = New-Object system.Windows.Forms.Label
$Label5.text                     = "Separator (eg. -):"
$Label5.AutoSize                 = $true
$Label5.width                    = 25
$Label5.height                   = 10
$Label5.location                 = New-Object System.Drawing.Point(60,130)
$Label5.Font                     = 'Microsoft Sans Serif,12'

$Label6                          = New-Object system.Windows.Forms.Label
$Label6.text                     = "Extension (eg. pdf):"
$Label6.AutoSize                 = $true
$Label6.width                    = 25
$Label6.height                   = 10
$Label6.location                 = New-Object System.Drawing.Point(60,95)
$Label6.Font                     = 'Microsoft Sans Serif,12'

$Button3                         = New-Object system.Windows.Forms.Button
$Button3.text                    = "Go"
$Button3.width                   = 60
$Button3.height                  = 30
$Button3.location                = New-Object System.Drawing.Point(165,240)
$Button3.Font                    = 'Microsoft Sans Serif,12'

$Button4                         = New-Object system.Windows.Forms.Button
$Button4.text                    = "Create 50 test files in Source"
$Button4.width                   = 140
$Button4.height                  = 50
$Button4.location                = New-Object System.Drawing.Point(120,285)
$Button4.Font                    = 'Microsoft Sans Serif,10'
$Form.controls.AddRange(@($TextBox1,$TextBox2,$Button1,$Button2,$Label1,$Label2,$ComboBox1,$Label3,$Label4,$TextBox3,$Label5,$Button3,$Button4,$TextBox4,$Label6))

$Button1.Add_Click({
  $TextBox1.Text = (FileBrowser)
})

$Button2.Add_Click({
  $TextBox2.Text = (FileBrowser)
})

$Button3.Add_Click({
  if (!(($TextBox1.Text -eq '') -and ($TextBox2.Text -eq ''))) {
    $dest = $TextBox2.Text
    $files = Get-ChildItem "$($TextBox1.Text)\*.$($TextBox4.Text)" -File

    for ($i = 0; $i -lt $files.Count; $i++) {
      $folder = $null
      if ($TextBox3.Text -eq '') {
        $folder = (Split-Path -Leaf $files[$i]).Substring(0, $ComboBox1.SelectedItem).Trim()
      } else {
        $sep = (Split-Path -Leaf $files[$i]).IndexOf($TextBox3.Text)
          switch ($sep) {
            -1 {continue}
            0  {$folder = (Split-Path -Leaf $files[$i]).Substring(0, 1).Trim()
              break
             }
          default {$folder = (Split-Path -Leaf $files[$i]).Substring(0, $sep).Trim()}
        }
      }
      if ($folder -ne $null) {
        if (!(Test-Path "$($dest)\$($folder)")) {
          New-Item -ItemType Directory "$($dest)\$($folder)"
        }
        Move-Item $files[$i] "$($dest)\$($folder)\$((Split-Path -Leaf $files[$i]))"
      }
    }
  }
})

$Button4.Add_Click({
  if (!($TextBox1.Text -eq '')) {
# Set the initial value to control the do loop
    $seed = 0
# How many files should be generated
    $random = 50
# File size in bytes
    $ranSize = 4096
# Path where the file will be created
    $ranPath = "$($TextBox1.Text)\"
    do {
      $netFn = [System.IO.Path]::GetRandomFileName()
      $netfn = [System.IO.Path]::ChangeExtension($netFn, $TextBox4.Text)
      fsutil file createnew $ranPath$netFn $ranSize
      $seed++
    } until ($seed -eq $random)
  }
})

#endregion events }

#endregion GUI }

#Write your logic code here

[void]$Form.ShowDialog()
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

tabzilla

  • Participant
  • Joined in 2019
  • *
  • Posts: 13
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #9 on: October 14, 2019, 12:30 PM »
That's great.  It's neater than keeping four AHK scripts on my desktop for one character, two characters, three characters and " - ".  Thank you.

Original address: https://www.donationcoder.com/forum/index.php?topic=48851.0