0

Can You give me tips how I can add to copied files name the prefix comes from name of sub-directory for example

this is my source dir '/home/ip/input/IP10/STAT-IP_202211151610_7428/some_files'

import os
import glob
import shutil


for f in glob.glob('/opt/data/input/IP10/**/*.*', recursive=True):
    shutil.copy(f, '/opt/data/input/IP10_for_decoder/copy/')

then I need to get file name after it copied: STAT-IP_202211151610_7428_some_files ?

stanny
  • 3
  • 4

2 Answers2

0

This might help:

import os, glob, shutil

rootpath = os.path.join("..", "Desktop", "*")

for f in glob.glob(os.path.join(rootpath, 'IP10/**/*.*'), recursive=True):
    last_two = os.path.join(*f.split(os.sep)[-2:]) # get two last path items. I.e. dir/file.txt
    shutil.copy(f, os.path.join(rootpath, 'IP10_for_decoder/copy/', last_two)) # add last two to end

This is assuming that within the IP10 folder you only have one directory and one file. If there are directory trees then you'd need a slightly different approach.

EDIT: Fix os.path.join input convention

  • yeap but anyway thanks for above Traceback (most recent call last): File "copy.py", line 16, in rootpath = os.path.join(["opt", "data", "input"]) File "/opt/pypy/lib/pypy3.9/posixpath.py", line 76, in join a = os.fspath(a) TypeError: expected str, bytes or os.PathLike object, not list – stanny Nov 15 '22 at 17:08
  • My mistake, the `os.path.join` function takes in multiple args, not a list of items. I edited the answer to fix this. Hopefully the new version helps. – Steinn Hauser Magnússon Nov 15 '22 at 18:10
  • @stanny do you have an update on this question? Did the edit of my answer I provided end up working for you? – Steinn Hauser Magnússon Nov 17 '22 at 12:51
  • Many Thanks for finding out the solution. – stanny Dec 02 '22 at 11:42
  • Great! You're very welcome. If this solves your issue you can mark the answer as the solution so that the thread can be closed – Steinn Hauser Magnússon Dec 02 '22 at 12:07
0

This question is definitely a duplicate of this.

Using os is fine, but my preference is pathlib's Path module - it handles windows and linux / unix paths real well, so makes for easy cross platform utilization. It has various methods already built into it, so you "don't have to" import glob and os modules for moving files, checking if they exist, etc:

With the help of this answer from the question linked above, we can do this:

from pathlib import Path
import shutil

path = Path(r"/opt/data/input/IP10/")
abs_path = path.absolute().parent # the path to the `Path` directory's parent directory

# there is a glob method as well.
# rglob is the recursive method.
for f in path.rglob('**/*.*'):
    dir_name = f.parent.stem # the parent directory's name
    name = f.with_name(f"{dir_name}_{f.name}").name # the new name of the file
    shutil.copy(f, f'{abs_path}/IP10_for_decoder/copy/{name}')

Some nice examples of what can be done with Path:

path = Path("./kansas.png")

path.stem # -> kansas
path.name # -> kansas.png
path.suffix # -> .png - if no "." in the filename, this will return an empty string
path.with_suffix(".jpg") # -> kansas.jpg
path.with_stem("texas") # -> texas.png
path.with_name("texas.jpg") # -> texas.jpg


path.absolute() # -> returns "/opt/data/input/IP10/kansas.png"
path.exists() # -> returns a boolean if it exists
path.parent # -> on absolute paths returns the full path to the parent directory
path.unlink() # deletes the file
path.touch() # "touches" the file
# replace and rename are a little hard to distinguish the difference between, imo, but both return a new path
path = path.replace(Path("/new/location/new_name.jpg"))
path = path.rename("new_file_name.jpg") # will rename the file

I thought there was a copy method for pathlib's Path, but nope.

There are a myriad of other operations - .parts splits the path into a list of directories and the filename that make up the path, you can read and write bytes and text to and from a file, .chmod a file or directory, and so on. Here is the documentation.

Shmack
  • 1,933
  • 2
  • 18
  • 23
  • Yes it looks so good but something goes wrong FileNotFoundError: [Errno 2] No such file or directory: '/opt/data/input/IP10_for_decoder/copy//opt/data/input/input_IP10' – stanny Nov 16 '22 at 07:15
  • @stanny Okay, this should work now. If not, I will check in the morning. – Shmack Nov 16 '22 at 08:16
  • Update: had to change `dir_name = path.parent.stem` to `dir_name = f.parent.stem`. – Shmack Nov 16 '22 at 08:22