-1

I need to move files to multiple folders by using Python. I have a folder with some files:

aa0123_0.sql
aa0123_1.sql
bb9876_0.sql
bb9876_1.sql
cc5555_0.sql
cc5555_1.sql

I would like to take only the files ending with _0.sql so aa0123_0.sql, bb9876_0.sql, cc5555_0.sql and replace the "_0" with "_data_for_bi" so file would be renamed to aa0123_data_for_bi.sql, ...

Additionally I need to move them to separate folders: AA, BB and CC. So files starting with aa for example "aa0123_0.sql" needs to be in AA folder, starting with bb to BB folder and starting with cc to CC folder.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
My80
  • 145
  • 9
  • 1
    What have you tried so far? Take a look at the Python libraries [pathlib](https://docs.python.org/3/library/pathlib.html) and [shutil](https://docs.python.org/3/library/shutil.html). – Louis Lac Jan 18 '22 at 16:42
  • What about files ending with `_1`? – Tomerikoo Jan 18 '22 at 16:43
  • I don't need files with _1 I just need files with_0. – My80 Jan 18 '22 at 16:47
  • I used this to move and rename files https://stackoverflow.com/questions/42541748/rename-and-move-file-with-python – My80 Jan 18 '22 at 16:50
  • Does this answer your question? [Rename and move file with Python](https://stackoverflow.com/questions/42541748/rename-and-move-file-with-python) – Louis Lac Jan 18 '22 at 16:54
  • No it's not all I need. I need to take only files with _0 and move them to seperate folders based on if they start with aa then to folder AA if they start with bb to BB folder... – My80 Jan 18 '22 at 16:55
  • Does this answer your question? https://stackoverflow.com/questions/63488416/python-move-files-from-current-path-to-specific-folder-named-like-or-similar-to – Tomerikoo Jan 19 '22 at 12:09

3 Answers3

1

Since Python 3.4, working with paths is most easily done with pathlib. Let's break it down to steps:

  1. Only take files ending with _0. Using glob you can pass a pattern of the files you want to iterate over:

    from pathlib import Path
    
    root = Path("path/to/folder")
    for path in root.glob("*_0*"):
        ...
    
  2. Find the matching folder to move to. That's simply taking the first two characters of the name:

        new_folder = Path("path/to/new/root", path.name[:2].upper())
    

    Create it in case it doesn't already using mkdir. The argument exist_ok set to True means it will not fail next time:

        new_folder.mkdir(exist_ok=True)
    
  3. Rename the file using with_stem (Python >= 3.9):

        new_name = path.with_stem(path.stem.rpartition('_0')[0] + "_data_for_bi").name
    
  4. Move the file to the new folder with the new name using rename:

        path.rename(new_folder / new_name)
    
  5. All together:

    from pathlib import Path
    
    root = Path("path/to/folder")
    for path in root.glob("*_0*"):
        new_folder = Path(path.name[:2].upper())
        new_folder.mkdir(exist_ok=True)
        new_name = path.with_stem(path.stem.rpartition('_0')[0] + "_data_for_bi").name
        path.rename(new_folder / new_name)
    
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
0

If i understood your question, that should do the trick :

import os
# Get the list of files in the current directory
files = os.listdir('.')

for f in files:
    # remove the path if needed
    filename = os.path.basename(f)
    # remove the extension
    basename = os.path.splitext(filename)[0]
    # If filename doesnt contains "_0", skip the file
    if (basename[-2:] != '_0'):
        continue ;
    # Get folder from the first 2 chars of the filename
    folder = (basename[:2]).upper()
    # generate new name
    new_name = basename[:-1] + 'data_for_bi.sql'
    # Put folder and filename together
    target = os.path.join(folder, new_name)
    # Move the file
    os.rename(f, target)

does it help ?

== EDIT ==

You can of course replace os.listdir('.') with os.listdir('C:\\path\\to\files\\') but don't forget to also specify the target. You can put it in os.path.join('path', 'to', 'file')

Also if you are on windows sub-system linux, C:\path\to\file will be /mnt/c/path/to/file/

vinalti
  • 966
  • 5
  • 26
  • Can I put my path and not to use os.listdir('.')? I need to use just one folder. For example C:\\Users\\xxx\data\folder_xxx and move to separate folders AA,BB,CC. – My80 Jan 18 '22 at 17:04
  • You would need to put your path inside the bracket : `os.listdir('C:\\Users\\xxx\data\folder_xxx')` and to adjust target to be the good directory. `os.listdir` should list the files inside a specified directory. --- (Please up-vote my comment or mark it as solution if it helped) – vinalti Jan 18 '22 at 17:08
  • how can I specify target? – My80 Jan 18 '22 at 18:25
  • Depends on where you are. The simplest would be to move (cd) in the good directory, before to execute the script. Then every folder will be created in the current directory (where you are). Otherwise, clean option: `target = os.path.join("C:","path","to","folder", folder, new_name)` Will generate : `C:\path\to\folder\AA\xxxxxxxx.sql` Or you can make it dirty: `target="C:\\path\\to\\folder\\" + os.path.join(folder, new_name)` – vinalti Jan 18 '22 at 18:31
  • I have error the system cannot find file specified. I have target = os.path.join("C:","path","to","folder", folder, new_name) – My80 Jan 18 '22 at 18:57
  • did you replace `"path", "to", "folder"` with the real path? make a print before hand to make sure it exist. also be careful with it as you're moving files you could lose some data by mistake, comment the "rename" line until you're sure the path is correct. Because you're working on windows make sure the path should be written like this. – vinalti Jan 18 '22 at 19:26
  • yes I did I added ("C:",Users\\xxx\\xxx") – My80 Jan 18 '22 at 19:35
  • do `print(target)` to see what's displayed and try to figure out the problems in the path. Also tell me more about the OS and how you run the script if you want me to be more helpful – vinalti Jan 18 '22 at 20:13
0

I would have a look at Python's os and shutil libraries. If I understood your question correctly, the following code should do the trick:

import os
import shutil

path_to_folder = 'C:/Users/Name/...' 
os.chdir(path_to_root_folder)

contents = os.listdir()

for filename in contents:
    if '_0.sql' in filename:
        new_filename    = filename.replace('_0.sql', '_data_for_bi.sql')
        new_filepath = f'{filename[:2].upper()}/{new_filename}'
        shutil.move(filename, new_filepath)

This requires that the folders /AA, /BB, /CC, etc. exist already. If not, you can create them using the os.mkdir(path) function within the for-loop.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
amundsno
  • 1
  • 2