Python Forum
Python Folders Splitter to Files Splitter
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python Folders Splitter to Files Splitter
#11
(Mar-01-2025, 05:37 PM)snippsat Wrote: The folder naming seems to work initially but fails to update correctly after a certain poin,especially with the ZX Chip Vologodonsk files.
The counter variable might not be resetting properly after each folder is created.
Fix counter so it reset to 0 after every filesperfolder files, ensuring a new folder is created consistently.
from pathlib import Path
from shutil import move

# Get the current working directory as a Path object
wd = Path.cwd()
files = [f for f in wd.iterdir() if f.is_file()]
lastitemindex = len(files) - 1
results = Path(wd.drive) / "/c64Romset_output"
filesperfolder = 5  # Set to 5 for testing; adjust as needed
letterstodisplay = 15
results.mkdir(parents=True, exist_ok=True)

# Open log file
log_output = (results / "log_output.txt").open("w+")
tally = 0
counter = 0
folder_index = 0
for i, file in enumerate(files):
    tally += 1
    # Create a new folder (reached filesperfolder limit)
    if counter == 0:
        start_idx = i
        end_idx = min(i + filesperfolder - 1, lastitemindex)
        firstfn_2l = files[start_idx].name[:letterstodisplay].split("(")[0].strip().upper()[:4]
        lastfn_2l = files[end_idx].name[:letterstodisplay].split("(")[0].strip().upper()[:4]
        target = f"{firstfn_2l} to {lastfn_2l}".strip()
        (results / target).mkdir(exist_ok=True)
        print(f"Created new directory: {target}")

    # Move the file to the target folder
    newfname = file.name.split("(")[0].strip()
    move(file, results / target / newfname)
    print(f"Moved {file.name} to {results / target} as {newfname}")
    log_output.write(f"\nMoved {file.name} to: ** {target} ** as {newfname}")
    counter += 1
    # Reset counter and prepare for the next folder
    if counter == filesperfolder:
        counter = 0
        folder_index += 1

if __name__ == "__main__":
    print(f"{tally} files processed ... ALL DONE")
    log_output.write(f"\
Gribouillis code is better and work for me if i do one change.
from pathlib import Path
from shutil import move

# Get the current working directory as a Path object
wd = Path.cwd()
# Setup output directory and parameters
# add one /
results = Path(wd.drive) / "/c64Romset_output"
filesperfolder = 5  # My test set 255
letterstodisplay = 15
# split list of files into chunks
files = [f for f in wd.iterdir() if f.is_file()]
chunks = [files[i : i + filesperfolder] for i in range(0, len(files), filesperfolder)]

# function to shorten names
def short(name):
    return name[:letterstodisplay].split("(")[0].strip().upper()[:4]

log_output = (results / "log_output.txt").open("w+")

tally = 0
for files in chunks:
    target = f"{short(files[0].name)} to {short(files[-1].name)}".strip()
    print(f"{tally} files processed ... making new dir called: {target}")
    (results / target).mkdir(parents=True, exist_ok=True)
    for file in files:
        # Move the file to the target folder
        newfname = file.name.split("(")[0].strip()
        move(file, results / target / newfname)
        print(f"Moved {file.name} to {results / target} as {newfname}")
        log_output.write(f"\nMoved {file.name} to: ** {target} ** as {newfname}")
    tally += len(files)


if __name__ == "__main__":
    print(f"{tally} files processed ... ALL DONE")
    log_output.write(f"\n{tally} files processed.")
    log_output.close()

I just tried the new Griboullis one, another time an error:

Error:
C:\FileSplitter>fileSplitterGriboullis.py Traceback (most recent call last): File "C:\FileSplitter\fileSplitterGriboullis.py", line 19, in <module> log_output = (results / "log_output.txt").open("w+") File "C:\Users\stefa\AppData\Local\Programs\Python\Python313\Lib\pathlib\_local.py", line 537, in open return io.open(self, mode, buffering, encoding, errors, newline) ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: 'C:\\c64Romset_output\\log_output.txt'
Reply
#12
(Mar-01-2025, 05:37 PM)snippsat Wrote: The folder naming seems to work initially but fails to update correctly after a certain poin,especially with the ZX Chip Vologodonsk files.
The counter variable might not be resetting properly after each folder is created.
Fix counter so it reset to 0 after every filesperfolder files, ensuring a new folder is created consistently.
from pathlib import Path
from shutil import move

# Get the current working directory as a Path object
wd = Path.cwd()
files = [f for f in wd.iterdir() if f.is_file()]
lastitemindex = len(files) - 1
results = Path(wd.drive) / "/c64Romset_output"
filesperfolder = 5  # Set to 5 for testing; adjust as needed
letterstodisplay = 15
results.mkdir(parents=True, exist_ok=True)

# Open log file
log_output = (results / "log_output.txt").open("w+")
tally = 0
counter = 0
folder_index = 0
for i, file in enumerate(files):
    tally += 1
    # Create a new folder (reached filesperfolder limit)
    if counter == 0:
        start_idx = i
        end_idx = min(i + filesperfolder - 1, lastitemindex)
        firstfn_2l = files[start_idx].name[:letterstodisplay].split("(")[0].strip().upper()[:4]
        lastfn_2l = files[end_idx].name[:letterstodisplay].split("(")[0].strip().upper()[:4]
        target = f"{firstfn_2l} to {lastfn_2l}".strip()
        (results / target).mkdir(exist_ok=True)
        print(f"Created new directory: {target}")

    # Move the file to the target folder
    newfname = file.name.split("(")[0].strip()
    move(file, results / target / newfname)
    print(f"Moved {file.name} to {results / target} as {newfname}")
    log_output.write(f"\nMoved {file.name} to: ** {target} ** as {newfname}")
    counter += 1
    # Reset counter and prepare for the next folder
    if counter == filesperfolder:
        counter = 0
        folder_index += 1

if __name__ == "__main__":
    print(f"{tally} files processed ... ALL DONE")
    log_output.write(f"\
Gribouillis code is better and work for me if i do one change.
from pathlib import Path
from shutil import move

# Get the current working directory as a Path object
wd = Path.cwd()
# Setup output directory and parameters
# add one /
results = Path(wd.drive) / "/c64Romset_output"
filesperfolder = 5  # My test set 255
letterstodisplay = 15
# split list of files into chunks
files = [f for f in wd.iterdir() if f.is_file()]
chunks = [files[i : i + filesperfolder] for i in range(0, len(files), filesperfolder)]

# function to shorten names
def short(name):
    return name[:letterstodisplay].split("(")[0].strip().upper()[:4]

log_output = (results / "log_output.txt").open("w+")

tally = 0
for files in chunks:
    target = f"{short(files[0].name)} to {short(files[-1].name)}".strip()
    print(f"{tally} files processed ... making new dir called: {target}")
    (results / target).mkdir(parents=True, exist_ok=True)
    for file in files:
        # Move the file to the target folder
        newfname = file.name.split("(")[0].strip()
        move(file, results / target / newfname)
        print(f"Moved {file.name} to {results / target} as {newfname}")
        log_output.write(f"\nMoved {file.name} to: ** {target} ** as {newfname}")
    tally += len(files)


if __name__ == "__main__":
    print(f"{tally} files processed ... ALL DONE")
    log_output.write(f"\n{tally} files processed.")
    log_output.close()

Your code Snappsat appear to work as expected, now, however he trunks filnames and extensions. Randomly some file remain with extension even if their name is very log, sometimes the code trunk the name even if it is short.
Obviously I don't need the name to be truncated :-( The file name should be exatly the same as the original one...
Many thanks if you should fix this last problem

Letters to display is related to how many long must be the name of the folder (example for selecting 5 is AAAAA to BBBBB) but the file name must not be changed

Tried also to set Letterstodisplay to 100, but the result is not changed, as you can see names are truncated randomply and folders are always 4 to 4 digits (AAAA to BBBB):
Output:
C:\FileSplitter>fileSplitterSnippsat.py Created new directory: 10TH to 3-D Moved 10th Frame.d64 to C:\c64Romset_output\10TH to 3-D as 10th Frame.d64 Moved 1941 - The Secret Conflict (USA) (Unl).T64 to C:\c64Romset_output\10TH to 3-D as 1941 - The Secret Conflict Moved 1942.d64 to C:\c64Romset_output\10TH to 3-D as 1942.d64 Moved 1943 - The Battle of Midway (USA).D64 to C:\c64Romset_output\10TH to 3-D as 1943 - The Battle of Midway Moved 3-D Tic Tac Toe (USA).T64 to C:\c64Romset_output\10TH to 3-D as 3-D Tic Tac Toe Created new directory: A-TE to AD I Moved A-Team, The (Netherlands).T64 to C:\c64Romset_output\A-TE to AD I as A-Team, The Moved Abyss (Europe).D64 to C:\c64Romset_output\A-TE to AD I as Abyss Moved Action Biker.d64 to C:\c64Romset_output\A-TE to AD I as Action Biker.d64 Moved Action Fighter (Europe).T64 to C:\c64Romset_output\A-TE to AD I as Action Fighter Moved Ad Infinitum.d64 to C:\c64Romset_output\A-TE to AD I as Ad Infinitum.d64 Created new directory: ADDA to AIRB Moved Addams Family, The (Europe).D64 to C:\c64Romset_output\ADDA to AIRB as Addams Family, The Moved Adventure (USA) (Unl).T64 to C:\c64Romset_output\ADDA to AIRB as Adventure Moved Adventures of Buckaroo Banzai, The (Graphic Version) (USA).D64 to C:\c64Romset_output\ADDA to AIRB as Adventures of Buckaroo Banzai, The Moved Afterburner (USA).D64 to C:\c64Romset_output\ADDA to AIRB as Afterburner Moved Airborne Ranger.d64 to C:\c64Romset_output\ADDA to AIRB as Airborne Ranger.d64 Created new directory: AIRW to ALF Moved Airwolf (Europe).T64 to C:\c64Romset_output\AIRW to ALF as Airwolf Moved Airwolf II (Europe).D64 to C:\c64Romset_output\AIRW to ALF as Airwolf II Moved Alcazar - The Forgotten Fortress.d64 to C:\c64Romset_output\AIRW to ALF as Alcazar - The Forgotten Fortress.d64 Moved ALCON (USA).D64 to C:\c64Romset_output\AIRW to ALF as ALCON Moved Alf - The First Adventure (USA).D64 to C:\c64Romset_output\AIRW to ALF as Alf - The First Adventure Created new directory: ALIE to AMAZ Moved Alien (SoftGold) (USA).D64 to C:\c64Romset_output\ALIE to AMAZ as Alien Moved Alien 3 (Europe).D64 to C:\c64Romset_output\ALIE to AMAZ as Alien 3 Moved Aliens - The Computer Game (USA).D64 to C:\c64Romset_output\ALIE to AMAZ as Aliens - The Computer Game Moved Alleykat.d64 to C:\c64Romset_output\ALIE to AMAZ as Alleykat.d64 Moved Amazing Spider-Man, The (USA).T64 to C:\c64Romset_output\ALIE to AMAZ as Amazing Spider-Man, The Created new directory: ANAR to ARKA Moved Anarchy.d64 to C:\c64Romset_output\ANAR to ARKA as Anarchy.d64 Moved Andy Capp.d64 to C:\c64Romset_output\ANAR to ARKA as Andy Capp.d64 Moved Arcade Trivia Quiz (Europe).D64 to C:\c64Romset_output\ANAR to ARKA as Arcade Trivia Quiz Moved Archon.d64 to C:\c64Romset_output\ANAR to ARKA as Archon.d64 Moved Arkanoid - Revenge Of Doh.d64 to C:\c64Romset_output\ANAR to ARKA as Arkanoid - Revenge Of Doh.d64 Created new directory: ARKA to ARNI Moved Arkanoid.d64 to C:\c64Romset_output\ARKA to ARNI as Arkanoid.d64 Moved Armalyte.d64 to C:\c64Romset_output\ARKA to ARNI as Armalyte.d64 Moved Army Moves.d64 to C:\c64Romset_output\ARKA to ARNI as Army Moves.d64 Moved Arnie II (Europe).T64 to C:\c64Romset_output\ARKA to ARNI as Arnie II Moved Arnie.d64 to C:\c64Romset_output\ARKA to ARNI as Arnie.d64 Created new directory: ASTE to AUF Moved Asteroids (Data Media) (Europe).T64 to C:\c64Romset_output\ASTE to AUF as Asteroids Moved Asteroids (Norbert Kehrer) (USA) (Unl).T64 to C:\c64Romset_output\ASTE to AUF as Asteroids Moved Asteroids 64 (Germany) (Unl).D64 to C:\c64Romset_output\ASTE to AUF as Asteroids 64 Moved Atomic Robo-Kid (USA).D64 to C:\c64Romset_output\ASTE to AUF as Atomic Robo-Kid Moved Auf Wiedersehen Monty.d64 to C:\c64Romset_output\ASTE to AUF as Auf Wiedersehen Monty.d64 Created new directory: AVEN to BACK Moved Avenger.d64 to C:\c64Romset_output\AVEN to BACK as Avenger.d64 Moved Avengers (USA).T64 to C:\c64Romset_output\AVEN to BACK as Avengers Moved Aztec Challenge.d64 to C:\c64Romset_output\AVEN to BACK as Aztec Challenge.d64 Moved Back to the Future (Europe).T64 to C:\c64Romset_output\AVEN to BACK as Back to the Future Moved Back to the Future II (Europe).zip to C:\c64Romset_output\AVEN to BACK as Back to the Future II Created new directory: BAD to BATM Moved Bad Dudes vs. Dragon Ninja (USA).D64 to C:\c64Romset_output\BAD to BATM as Bad Dudes vs. Dragon Ninja Moved Ballblazer (USA).T64 to C:\c64Romset_output\BAD to BATM as Ballblazer Moved Bandits.d64 to C:\c64Romset_output\BAD to BATM as Bandits.d64 Moved Barbarian.d64 to C:\c64Romset_output\BAD to BATM as Barbarian.d64 ...continue 693 files processed ... ALL DONE C:\FileSplitter>
Reply
#13
(Mar-01-2025, 06:07 PM)Guybrush16bit Wrote: now, however he trunks filnames and extensions. Randomly some file remain with extension even if their name is very log, sometimes the code trunk the name even if it is short.
Ok try this.
from pathlib import Path
from shutil import move

def split_files_into_folders(files_per_folder=5, letter_display=15):
    """Organize files into subfolders based on specified count."""   
    wd = Path.cwd()
    files = [f for f in wd.iterdir() if f.is_file()]
    if not files:
        print("No files to process.")
        return
    output_dir = wd.drive / Path("c64Romset_output")
    output_dir.mkdir(parents=True, exist_ok=True)
    # Process files in batches
    with (output_dir / "log_output.txt").open("w+") as log:
        for i, file in enumerate(files):
            if i % files_per_folder == 0:
                start_idx = i
                end_idx = min(i + files_per_folder - 1, len(files) - 1)
                first_prefix = files[start_idx].name[:letter_display].split("(")[0].strip().upper()[:4]
                last_prefix = files[end_idx].name[:letter_display].split("(")[0].strip().upper()[:4]
                folder_name = f"{first_prefix} to {last_prefix}".strip()
                target = output_dir / folder_name
                target.mkdir(exist_ok=True)
            # Move file with original name
            move(file, target / file.name)
            print(f"Moved {file.name} to {target}")
            log.write(f"\nMoved {file.name} to: ** {folder_name} **")
        # Summary
        total = len(files)
        print(f"{total} files processed ... ALL DONE")
        log.write(f"\n{total} files processed.")

if __name__ == "__main__":
    split_files_into_folders()
Fix for Gribouillis code.
from pathlib import Path
from shutil import move

# Get the current working directory as a Path object
wd = Path.cwd()
# Setup output directory and parameters
results = Path("C:/c64Romset_output")
results.mkdir(parents=True, exist_ok=True)
filesperfolder = 5  # My test set 255
letterstodisplay = 15
# split list of files into chunks
files = [f for f in wd.iterdir() if f.is_file()]
chunks = [files[i : i + filesperfolder] for i in range(0, len(files), filesperfolder)]

# function to shorten names
def short(name):
    return name[:letterstodisplay].split("(")[0].strip().upper()[:4]

log_output = (results / "log_output.txt")
tally = 0
for files in chunks:
    target = f"{short(files[0].name)} to {short(files[-1].name)}".strip()
    print(f"{tally} files processed ... making new dir called: {target}")
    (results / target).mkdir(parents=True, exist_ok=True)
    for file in files:
        # Move the file to the target folder
        newfname = file.name.split("(")[0].strip()
        move(file, results / target / newfname)
        print(f"Moved {file.name} to {results / target} as {newfname}")
        log_output.write_text(f"\nMoved {file.name} to: ** {target} ** as {newfname}")
    tally += len(files)

if __name__ == "__main__":
    print(f"{tally} files processed ... ALL DONE")
    log_output.write_text(f"\n{tally} files processed.")
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Using zipfile module - finding folders not files darter1010 2 2,215 Apr-06-2024, 07:22 AM
Last Post: Pedroski55
  Create new folders and copy files cocobolli 3 4,581 Mar-22-2023, 10:23 AM
Last Post: Gribouillis
  Copy only hidden files and folders with rsync Cannondale 2 2,331 Mar-04-2023, 02:48 PM
Last Post: Cannondale
  python move folders and subfolders not working mg24 5 4,464 Nov-09-2022, 02:24 PM
Last Post: Larz60+
  Moving files to Folders giddyhead 13 12,570 Mar-07-2021, 02:50 AM
Last Post: giddyhead
  code to read files in folders and transfer the file name, type, date created to excel Divya577 0 2,436 Dec-06-2020, 04:14 PM
Last Post: Divya577
  Calling Variables from Other Files in Different Folders illmattic 14 9,957 Aug-01-2020, 07:02 PM
Last Post: deanhystad
  sub-folders in folders from text line jenost 1 2,155 Mar-31-2020, 07:16 AM
Last Post: ndc85430
  Python script that recursively zips folders WITHOUT nesting the folder inside the zip umkc1 1 4,521 Feb-11-2020, 09:12 PM
Last Post: michael1789
  Python Script to repeat Photoshop action in folders and subfolders silfer 2 5,663 Jul-25-2019, 03:12 PM
Last Post: silfer

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020