Jump to content

Sorting files to folders


Recommended Posts

Hey all, 

currently I have to sort thousand of files like this:

123A.pdf
123Abc.doc
123Aaz.txt

321Aaffas.pdf
321Asdf.doc
321Aas.txt

213eq.pdf
213lvgs.doc
213sgd.txt

to folders like this:

123 Folder

321 Folder

213 Folder

So basicly the files and the folders (where the files should be placed) got the same number in the front. The rest can be different. 
Any Ideas which ist a smart way of doing it? If not any Ideas? :D

 

edit: all files and folders are stored in one folder. 

File names (numbers at the front) reaching from 1000000-XXX000000.

Also included Ä Ü Ö (im german) :D

best regards 

Edited by lordsocke
Link to comment
Share on other sites

  • Moderators

Are you saying that all "123" files are in "123" folder, and all "321" files are in "321" folder? Or are you saying you want to find all "123" files and move them to "123" folder?

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

1 hour ago, lordsocke said:

Any Ideas which ist a smart way of doing it? If not any Ideas? :D

Use _FileListToArray() to obtain a list of files in a folder, and then extract some information with SRE to create the various folders and move the corresponding files into them:

#include <Array.au3>
#include <File.au3>
#include <StringConstants.au3>

Global $strSourcePath = @ScriptDir & "\SampleFiles", _
       $arrFileList, _
       $strFolderName = "", _
       $strFileName = "", _
       $arrDestFileName = ""

$arrFileList = _FileListToArray($strSourcePath, "*", $FLTA_FILES, True)
If @error Then
    ConsoleWrite("_FileListToArray ERR: " & @error & @CRLF)
    Exit
Else

    For $i = 1 To $arrFileList[0] Step 1

        ; Getting the Folder Name
        $strFolderName = StringRegExp(StringRegExp($arrFileList[$i], '([^\\]+\..*)', $STR_REGEXPARRAYMATCH)[0], '(\d{3})', $STR_REGEXPARRAYMATCH)[0]

        ; Gettin the File Name
        $strFileName = StringRegExp($arrFileList[$i], '([^\\]+\..*)', $STR_REGEXPARRAYMATCH)[0]

        ; FolderName and FileName
        $arrDestFileName = @ScriptDir & "\Folders\" & $strFolderName & "\" & $strFileName

        ; Copying the files from SourceFolder to DestFolder.
        If FileCopy($arrFileList[$i], $arrDestFileName, $FC_CREATEPATH) Then ConsoleWrite("File copied from '" & $arrFileList[$i] & "' to '" & $arrDestFileName & "'." & @CRLF)

    Next

EndIf

:)
 

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

Not sure if AutoIt should be your hammer;-)

This is much easier from ISE Powershell. Be carefull when you test this as its much harder to get it back from multiple folders to your origin so make a backup.

clear-host
#Just some testdata
gci | out-file 1234.txt
gci | out-file 1235.txt
gci | out-file 3456.txt
gci | out-file 3457.txt

#actual command
Get-ChildItem |
    ForEach-Object{
        $dest='.\' + $_.name.Substring(0,3) 
        New-Item -ItemType directory $dest -force
        Move-Item $_.Fullname $dest -force
}

 

Link to comment
Share on other sites

3 hours ago, JLogan3o13 said:

Are you saying that all "123" files are in "123" folder, and all "321" files are in "321" folder? Or are you saying you want to find all "123" files and move them to "123" folder?

I want to find all 123 files and want to move them to „123“ folder :D

Link to comment
Share on other sites

14 hours ago, FrancescoDiMuro said:

Use _FileListToArray() to obtain a list of files in a folder, and then extract some information with SRE to create the various folders and move the corresponding files into them:

#include <Array.au3>
#include <File.au3>
#include <StringConstants.au3>

Global $strSourcePath = @ScriptDir & "\SampleFiles", _
       $arrFileList, _
       $strFolderName = "", _
       $strFileName = "", _
       $arrDestFileName = ""

$arrFileList = _FileListToArray($strSourcePath, "*", $FLTA_FILES, True)
If @error Then
    ConsoleWrite("_FileListToArray ERR: " & @error & @CRLF)
    Exit
Else

    For $i = 1 To $arrFileList[0] Step 1

        ; Getting the Folder Name
        $strFolderName = StringRegExp(StringRegExp($arrFileList[$i], '([^\\]+\..*)', $STR_REGEXPARRAYMATCH)[0], '(\d{3})', $STR_REGEXPARRAYMATCH)[0]

        ; Gettin the File Name
        $strFileName = StringRegExp($arrFileList[$i], '([^\\]+\..*)', $STR_REGEXPARRAYMATCH)[0]

        ; FolderName and FileName
        $arrDestFileName = @ScriptDir & "\Folders\" & $strFolderName & "\" & $strFileName

        ; Copying the files from SourceFolder to DestFolder.
        If FileCopy($arrFileList[$i], $arrDestFileName, $FC_CREATEPATH) Then ConsoleWrite("File copied from '" & $arrFileList[$i] & "' to '" & $arrDestFileName & "'." & @CRLF)

    Next

EndIf

:)
 

Here I wrote total bullshit: "Looks very nice, but some of the files got the name 54816382648173 so I think counting up the for loop will crash my CPU 😄. "

The script is working fine, but it is creating new folders containing the files. Actually I have to sort them into existing folders in the same path as the source files.

Desktop/foldername/ <- here is everything inside (files and folders in the same path)
345678-2019-06-06-philipp.pdf <- sorting this
345678-2019-06-06-philipp.doc <- sorting this
345678-2019-06-06-philipp.txt <- sorting this
345678-2019-06-06-philipp_Folder <- into this folder
345234-2019-07-04-tom.pdf 
345234-2019-07-04-tom.doc
345234-2019-07-04-tom.txt
345234-2019-07-04-tom_Folder
824567890-2018-02-20-melanie.pdf
824567890-2018-02-20-melanie.doc
824567890-2018-02-20-melanie.txt

...and so on

 

Edited by lordsocke
explaning
Link to comment
Share on other sites

22 minutes ago, junkew said:

Did you try either the powershell or autoit solution? Both fit to the requirements you have given. There is no issue with running out of cpu or arraybounds.

For beeing honestly Ive never worked with powershell, so I can edit the Autoit script from francesco so that its going to work out for me, but im not able to understand the powershell :D
If you got the time to explain it to me or sending me a link where is written what this actually does, lots of hugs :*

Link to comment
Share on other sites

https://ss64.com/ps/ is one of my favorite sites with explanation of powershell. Just type ise in windows start and you get the ps cmd editor and experiment. Powershell is the mainstream language for windows.

For your problem I just feel ps suits better then AutoIt but both can do what you want.

Link to comment
Share on other sites

Your requirements seems to be shifting and/or are differently interpreted

  • from 3 character prefix nnn prefixed file to nnn folder <characters>.<extension> to existing folder <characters>_folder
    So 
    you need a regex with groups lik
    1. for any number or dash
    2. followed by a string (defined as not beeing a number or a dash)
    3. followed by a dot
    4. followed by an string extension   
  • and when found it should move to matched group 2 string

 

Link to comment
Share on other sites

Ok just for the fun.

key is for your au3 or ps is the regex that splits your filename in groups to be "(^[\d\-]*)([^.]*)(.*)"

Powershell one liner (that why I feel you should do this from powershell)

    Get-ChildItem -file | % {$_.name -match "(^[\d\-]*)([^.]*)(.*)" | out-null; $dest='.\' + $matches[1]+$matches[2]+ "_Folder"; New-Item -ItemType directory $dest -force; Move-Item $_.Fullname $dest -force;  }

Powershell script like demo to make it more understandable

function example() {
    clear-host                                                      # clear the screen
    $testfolder= ("testfolder" + (get-date -format "hhmmss"))       # Variable with a dummy testfolder
    write-host "testing in folder $testfolder"                      # like consolewrite     
    new-item -itemtype directory $testfolder                        # creates the testfolder 
    cd $testfolder                                                  # makes sure we are in the testfolder
    create-testdata                                                 # create some dummy data 
    move-myfiles                                                    # and the actual movement embedded in a function 
}

#Just some testdata
# 1. dummy files
# 2. folders preexist as given in the requirements
function create-testdata() {
    "dummy text" | out-file 345678-2019-06-06-philipp.pdf 
    "dummy text" | out-file 345678-2019-06-06-philipp.doc 
    "dummy text" | out-file 345678-2019-06-06-philipp.txt 
    new-item -ItemType directory "345678-2019-06-06-philipp_Folder" -force

    "dummy text" | out-file 345234-2019-07-04-tom.pdf 
    "dummy text" | out-file 345234-2019-07-04-tom.doc
    "dummy text" | out-file 345234-2019-07-04-tom.txt
    new-item -ItemType directory "345234-2019-07-04-tom_Folder" -force

    "dummy text" | out-file 824567890-2018-02-20-melanie.pdf
    "dummy text" | out-file 824567890-2018-02-20-melanie.doc
    "dummy text" | out-file 824567890-2018-02-20-melanie.txt
    new-item -ItemType directory "824567890-2018-02-20-melanie_Folder" -force
}

#actual command
function move-MyFiles() {
    Get-ChildItem -file | % {
        $_.name -match "(^[\d\-]*)([^.]*)(.*)" | out-null;    # Split into default $matches variable
        $dest='.\' + $matches[1]+$matches[2]+ "_Folder";      # 0 = whole match, 1=group 1 matched, ... extend with "_Folder" as target
        New-Item -ItemType directory $dest -force;            # Although folder should be there force it to be there if not existing
        Move-Item $_.Fullname $dest -force;                   # do the actual move  
   }                 
}

example

and as an exercise the main part in AutoIt, you have to add your copy/move stuff in it wtih

https://www.autoitscript.com/autoit3/docs/functions/FileMove.htm

examples is just based on help file examples of filefindfirstfile

 you can enhance below but see the regex is key in the solution of splitting

#include <MsgBoxConstants.au3>
#include <StringConstants.au3>

Local $aArray = StringRegExp('345678-2019-06-06-philipp.pdf', "(^[\d\-]*)([^.]*)(.*)", $STR_REGEXPARRAYGLOBALMATCH)

consolewrite($aArray[0] & @CRLF)
consolewrite($aArray[1] & @CRLF)
consolewrite($aArray[2] & @CRLF)
#include <MsgBoxConstants.au3>
#include <StringConstants.au3>

Example()


Func Example()
    local $testfolder="<your test folder>\"   ; Make sure there are files in it

; Assign a Local variable the search handle of all files in the current directory.
    Local $hSearch = FileFindFirstFile($testfolder & "*.*")

    ; Check if the search was successful, if not display a message and return False.
    If $hSearch = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "Error: No files/directories matched the search pattern.")
        Return False
    EndIf

    ; Assign a Local variable the empty string which will contain the files names found.
    Local $sFileName = "", $iResult = 0

    While 1

        $tAttribute=FileGetAttrib ( $sFileName )

        if ($tAttribute <> 'D') then

            ; Display the file name.
            CONSOLEWRITE("File: " & $sFileName & @CRLF)

            Local $aArray = StringRegExp($sFileName, "(^[\d\-]*)([^.]*)(.*)", $STR_REGEXPARRAYGLOBALMATCH)

            consolewrite($aArray[0] & @CRLF)
            consolewrite($aArray[1] & @CRLF)
            consolewrite($aArray[2] & @CRLF)

            $sFileName = FileFindNextFile($hSearch)
            ; If there is no more file matching the search.
            If @error Then ExitLoop
        EndIf


    WEnd

    ; Close the search handle.
    FileClose($hSearch)
EndFunc   ;==>Example

 

Edited by junkew
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...