topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Thursday March 28, 2024, 6:31 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

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

tabzilla

  • Participant
  • Joined in 2019
  • *
  • default avatar
  • Posts: 13
    • View Profile
    • Donate to Member
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,169
    • View Profile
    • Donate to Member
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #1 on: October 08, 2019, 04:37 AM »
This should do it.

Code: Autohotkey [Select]
  1. SetWorkingDir %A_ScriptDir%
  2.  
  3. ;AutoHotkey script to move files into subfolders named after the filename's first two characters
  4. ;by Nod5 2019-10-08
  5.  
  6. ;How to use:
  7. ;0. install https://www.autohotkey.com/
  8. ;1. edit the next line with a path to the files folder. For example "C:\folder\S"
  9. folder := ""
  10. ;2. save the script with .ahk extension and UTF-8 BOM encoding and run it
  11.  
  12. ;Check that the folder exists
  13. If !InStr( FileExist(folder), "D")
  14.  
  15. Loop, Files, %folder%\*.*
  16. {
  17.   tooltip `n Moving files into subfolders ...
  18.  
  19.   ;get filename's first two characters as uppercase
  20.   two_chars := SubStr(A_LoopFileName, 1, 2)
  21.   two_chars := Format("{:U}", two_chars)
  22.  
  23.   ;create subfolder if not already exists
  24.   If !FileExist(folder "\" two_chars)
  25.     FileCreateDir % folder "\" two_chars
  26.  
  27.   ;move file to subfolder
  28.   FileMove, % A_LoopFilePath, % folder "\" two_chars
  29. }


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

Code: Autohotkey [Select]
  1. SetWorkingDir %A_ScriptDir%
  2.  
  3. ;AutoHotkey script to generate 75 empty text files named with the format
  4. ;sa_1.txt , sa_2.txt , sa_3.txt , sb_1.txt ...
  5.  
  6. chars := "abcdefghijklmnopqrstuvxyz"
  7. test_folder := A_ScriptDir "\" A_Now
  8. FileCreateDir, % test_folder
  9. Loop, Parse, chars
  10.   Loop, 3
  11.     FileAppend,, % test_folder "\s" A_LoopField "_" A_Index ".txt"
« Last Edit: October 08, 2019, 03:06 PM by Nod5, Reason: fixed typo »

tabzilla

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

tabzilla

  • Participant
  • Joined in 2019
  • *
  • default avatar
  • Posts: 13
    • View Profile
    • Donate to Member
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #3 on: October 10, 2019, 02: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
  • *
  • default avatar
  • Posts: 13
    • View Profile
    • Donate to Member
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #4 on: October 10, 2019, 03: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
  • *
  • default avatar
  • Posts: 13
    • View Profile
    • Donate to Member
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #5 on: October 11, 2019, 02:32 PM »
I've found a script that works for that here:

https://autohotkey.c...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,169
    • View Profile
    • Donate to Member
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #6 on: October 12, 2019, 03: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 [Select]
  1. SetWorkingDir %A_ScriptDir%
  2.  
  3. ;AutoHotkey script to move files into subfolders named after the string before " - " in the filename
  4. ;Example: the file "Lastname, Firstname - Title.txt" is moved to subfolder "Lastname, Firstname"
  5. ;by Nod5 2019-10-12
  6.  
  7. ;How to use:
  8. ;0. install https://www.autohotkey.com/
  9. ;1. edit the next line with a path to the files folder. For example "C:\folder\S"
  10. folder := ""
  11. ;2. save the script with .ahk extension and UTF-8 BOM encoding and run it
  12.  
  13. ;Check that the folder exists
  14. If !InStr( FileExist(folder), "D")
  15.  
  16. Loop, Files, %folder%\*.*
  17. {
  18.   tooltip `n Moving files into subfolders ...
  19.  
  20.   ;get string before " - " in filename
  21.   pattern := RegExReplace(A_LoopFileName, " - .*", "")
  22.  
  23.   ;create subfolder if not already exists
  24.   If !FileExist(folder "\" pattern)
  25.     FileCreateDir % folder "\" pattern
  26.  
  27.   ;move file to subfolder
  28.   FileMove, % A_LoopFilePath, % folder "\" pattern
  29. }

tabzilla

  • Participant
  • Joined in 2019
  • *
  • default avatar
  • Posts: 13
    • View Profile
    • Donate to Member
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #7 on: October 13, 2019, 05:23 AM »
Much appreciated.

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: IDEA: Like FileSieve but folders have first two letters of file
« Reply #8 on: October 14, 2019, 02: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 [Select]
  1. <# This form was created using POSHGUI.com  a free online gui designer for PowerShell
  2. .NAME
  3.     Refile.ps1
  4. #>
  5.  
  6. Function FileBrowser {
  7.   $objForm = New-Object System.Windows.Forms.FolderBrowserDialog
  8.   $objForm.Description = "Select folder containing files"
  9.   $objForm.SelectedPath = [System.Environment+SpecialFolder]'MyComputer'
  10.   $objForm.ShowNewFolderButton = $false
  11.   $result = $objForm.ShowDialog()
  12.   if ($result -eq "OK") {
  13.     return $objForm.SelectedPath
  14.   } else {
  15.     return ""
  16.   }
  17. }
  18.  
  19. #region begin GUI{
  20.  
  21. Add-Type -AssemblyName System.Windows.Forms
  22. [System.Windows.Forms.Application]::EnableVisualStyles()
  23.  
  24. $Form                            = New-Object system.Windows.Forms.Form
  25. $Form.ClientSize                 = '400,350'
  26. $Form.text                       = "Refile"
  27. $Form.TopMost                    = $false
  28.  
  29. $TextBox1                        = New-Object system.Windows.Forms.TextBox
  30. $TextBox1.multiline              = $false
  31. $TextBox1.width                  = 225
  32. $TextBox1.height                 = 21
  33. $TextBox1.location               = New-Object System.Drawing.Point(85,19)
  34. $TextBox1.Font                   = 'Microsoft Sans Serif,12'
  35.  
  36. $TextBox2                        = New-Object system.Windows.Forms.TextBox
  37. $TextBox2.multiline              = $false
  38. $TextBox2.width                  = 225
  39. $TextBox2.height                 = 21
  40. $TextBox2.location               = New-Object System.Drawing.Point(85,60)
  41. $TextBox2.Font                   = 'Microsoft Sans Serif,12'
  42.  
  43. $Button1                         = New-Object system.Windows.Forms.Button
  44. $Button1.text                    = "..."
  45. $Button1.width                   = 40
  46. $Button1.height                  = 30
  47. $Button1.location                = New-Object System.Drawing.Point(323,17)
  48. $Button1.Font                    = 'Microsoft Sans Serif,12'
  49.  
  50. $Button2                         = New-Object system.Windows.Forms.Button
  51. $Button2.text                    = "..."
  52. $Button2.width                   = 40
  53. $Button2.height                  = 30
  54. $Button2.location                = New-Object System.Drawing.Point(323,58)
  55. $Button2.Font                    = 'Microsoft Sans Serif,12'
  56.  
  57. $Label1                          = New-Object system.Windows.Forms.Label
  58. $Label1.text                     = "Source:"
  59. $Label1.AutoSize                 = $true
  60. $Label1.width                    = 25
  61. $Label1.height                   = 10
  62. $Label1.location                 = New-Object System.Drawing.Point(20,19)
  63. $Label1.Font                     = 'Microsoft Sans Serif,12'
  64.  
  65. $Label2                          = New-Object system.Windows.Forms.Label
  66. $Label2.text                     = "Dest:"
  67. $Label2.AutoSize                 = $true
  68. $Label2.width                    = 25
  69. $Label2.height                   = 10
  70. $Label2.location                 = New-Object System.Drawing.Point(20,59)
  71. $Label2.Font                     = 'Microsoft Sans Serif,12'
  72.  
  73. $ComboBox1                       = New-Object system.Windows.Forms.ComboBox
  74. $ComboBox1.width                 = 80
  75. $ComboBox1.height                = 20
  76. @('1','2','3','4','5') | ForEach-Object {[void] $ComboBox1.Items.Add($_)}
  77. $ComboBox1.location              = New-Object System.Drawing.Point(230,190)
  78. $ComboBox1.Font                  = 'Microsoft Sans Serif,12'
  79.  
  80. $Label3                          = New-Object system.Windows.Forms.Label
  81. $Label3.text                     = "Use first x characters:"
  82. $Label3.AutoSize                 = $true
  83. $Label3.width                    = 25
  84. $Label3.height                   = 10
  85. $Label3.location                 = New-Object System.Drawing.Point(60,193)
  86. $Label3.Font                     = 'Microsoft Sans Serif,12'
  87.  
  88. $Label4                          = New-Object system.Windows.Forms.Label
  89. $Label4.text                     = "or"
  90. $Label4.AutoSize                 = $true
  91. $Label4.width                    = 25
  92. $Label4.height                   = 10
  93. $Label4.location                 = New-Object System.Drawing.Point(188,160)
  94. $Label4.Font                     = 'Microsoft Sans Serif,12'
  95.  
  96. $TextBox3                        = New-Object system.Windows.Forms.TextBox
  97. $TextBox3.multiline              = $false
  98. $TextBox3.width                  = 80
  99. $TextBox3.height                 = 20
  100. $TextBox3.Text                   = ''
  101. $TextBox3.location               = New-Object System.Drawing.Point(230,130)
  102. $TextBox3.Font                   = 'Microsoft Sans Serif,12'
  103.  
  104. $TextBox4                        = New-Object system.Windows.Forms.TextBox
  105. $TextBox4.multiline              = $false
  106. $TextBox4.width                  = 80
  107. $TextBox4.height                 = 20
  108. $TextBox4.Text                   = 'txt'
  109. $TextBox4.location               = New-Object System.Drawing.Point(230,95)
  110. $TextBox4.Font                   = 'Microsoft Sans Serif,12'
  111.  
  112. $Label5                          = New-Object system.Windows.Forms.Label
  113. $Label5.text                     = "Separator (eg. -):"
  114. $Label5.AutoSize                 = $true
  115. $Label5.width                    = 25
  116. $Label5.height                   = 10
  117. $Label5.location                 = New-Object System.Drawing.Point(60,130)
  118. $Label5.Font                     = 'Microsoft Sans Serif,12'
  119.  
  120. $Label6                          = New-Object system.Windows.Forms.Label
  121. $Label6.text                     = "Extension (eg. pdf):"
  122. $Label6.AutoSize                 = $true
  123. $Label6.width                    = 25
  124. $Label6.height                   = 10
  125. $Label6.location                 = New-Object System.Drawing.Point(60,95)
  126. $Label6.Font                     = 'Microsoft Sans Serif,12'
  127.  
  128. $Button3                         = New-Object system.Windows.Forms.Button
  129. $Button3.text                    = "Go"
  130. $Button3.width                   = 60
  131. $Button3.height                  = 30
  132. $Button3.location                = New-Object System.Drawing.Point(165,240)
  133. $Button3.Font                    = 'Microsoft Sans Serif,12'
  134.  
  135. $Button4                         = New-Object system.Windows.Forms.Button
  136. $Button4.text                    = "Create 50 test files in Source"
  137. $Button4.width                   = 140
  138. $Button4.height                  = 50
  139. $Button4.location                = New-Object System.Drawing.Point(120,285)
  140. $Button4.Font                    = 'Microsoft Sans Serif,10'
  141. $Form.controls.AddRange(@($TextBox1,$TextBox2,$Button1,$Button2,$Label1,$Label2,$ComboBox1,$Label3,$Label4,$TextBox3,$Label5,$Button3,$Button4,$TextBox4,$Label6))
  142.  
  143. $Button1.Add_Click({
  144.   $TextBox1.Text = (FileBrowser)
  145. })
  146.  
  147. $Button2.Add_Click({
  148.   $TextBox2.Text = (FileBrowser)
  149. })
  150.  
  151. $Button3.Add_Click({
  152.   if (!(($TextBox1.Text -eq '') -and ($TextBox2.Text -eq ''))) {
  153.     $dest = $TextBox2.Text
  154.     $files = Get-ChildItem "$($TextBox1.Text)\*.$($TextBox4.Text)" -File
  155.  
  156.     for ($i = 0; $i -lt $files.Count; $i++) {
  157.       $folder = $null
  158.       if ($TextBox3.Text -eq '') {
  159.         $folder = (Split-Path -Leaf $files[$i]).Substring(0, $ComboBox1.SelectedItem).Trim()
  160.       } else {
  161.         $sep = (Split-Path -Leaf $files[$i]).IndexOf($TextBox3.Text)
  162.           switch ($sep) {
  163.             -1 {continue}
  164.             0  {$folder = (Split-Path -Leaf $files[$i]).Substring(0, 1).Trim()
  165.               break
  166.              }
  167.           default {$folder = (Split-Path -Leaf $files[$i]).Substring(0, $sep).Trim()}
  168.         }
  169.       }
  170.       if ($folder -ne $null) {
  171.         if (!(Test-Path "$($dest)\$($folder)")) {
  172.           New-Item -ItemType Directory "$($dest)\$($folder)"
  173.         }
  174.         Move-Item $files[$i] "$($dest)\$($folder)\$((Split-Path -Leaf $files[$i]))"
  175.       }
  176.     }
  177.   }
  178. })
  179.  
  180. $Button4.Add_Click({
  181.   if (!($TextBox1.Text -eq '')) {
  182. # Set the initial value to control the do loop
  183.     $seed = 0
  184. # How many files should be generated
  185.     $random = 50
  186. # File size in bytes
  187.     $ranSize = 4096
  188. # Path where the file will be created
  189.     $ranPath = "$($TextBox1.Text)\"
  190.     do {
  191.       $netFn = [System.IO.Path]::GetRandomFileName()
  192.       $netfn = [System.IO.Path]::ChangeExtension($netFn, $TextBox4.Text)
  193.       fsutil file createnew $ranPath$netFn $ranSize
  194.       $seed++
  195.     } until ($seed -eq $random)
  196.   }
  197. })
  198.  
  199. #endregion events }
  200.  
  201. #endregion GUI }
  202.  
  203. #Write your logic code here
  204.  
  205. [void]$Form.ShowDialog()

tabzilla

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